diff --git a/packages/ai-tools/dist/types_kbot.d.ts b/packages/ai-tools/dist/types_kbot.d.ts index 18b819c2..93ab5775 100644 --- a/packages/ai-tools/dist/types_kbot.d.ts +++ b/packages/ai-tools/dist/types_kbot.d.ts @@ -27,10 +27,14 @@ export interface IKBotOptions { aetherwiing/mn-starcannon-12b | paid ai21/jamba-1-5-large | paid ai21/jamba-1-5-mini | paid + ai21/jamba-1.6-large | paid ai21/jamba-instruct | paid + ai21/jamba-1.6-mini | paid aion-labs/aion-1.0 | paid aion-labs/aion-1.0-mini | paid aion-labs/aion-rp-llama-3.1-8b | paid + jondurbin/airoboros-l2-70b | paid + allenai/olmo-2-0325-32b-instruct | paid amazon/nova-lite-v1 | paid amazon/nova-micro-v1 | paid amazon/nova-pro-v1 | paid @@ -48,6 +52,9 @@ export interface IKBotOptions { anthropic/claude-3.5-sonnet-20240620 | paid anthropic/claude-3.5-sonnet-20240620:beta | paid anthropic/claude-3.5-sonnet:beta | paid + anthropic/claude-3.7-sonnet | paid + anthropic/claude-3.7-sonnet:beta | paid + anthropic/claude-3.7-sonnet:thinking | paid anthropic/claude-2 | paid anthropic/claude-2:beta | paid anthropic/claude-2.0 | paid @@ -56,6 +63,7 @@ export interface IKBotOptions { anthropic/claude-2.1:beta | paid openrouter/auto | paid cohere/command | paid + cohere/command-a | paid cohere/command-r | paid cohere/command-r-03-2024 | paid cohere/command-r-08-2024 | paid @@ -63,18 +71,21 @@ export interface IKBotOptions { cohere/command-r-plus-04-2024 | paid cohere/command-r-plus-08-2024 | paid cohere/command-r7b-12-2024 | paid - databricks/dbrx-instruct | paid - deepseek/deepseek-chat-v2.5 | paid + deepseek/deepseek-r1-zero:free | free deepseek/deepseek-chat | paid deepseek/deepseek-chat:free | free deepseek/deepseek-r1 | paid deepseek/deepseek-r1:free | free deepseek/deepseek-r1-distill-llama-70b | paid deepseek/deepseek-r1-distill-llama-70b:free | free + deepseek/deepseek-r1-distill-llama-8b | paid deepseek/deepseek-r1-distill-qwen-1.5b | paid deepseek/deepseek-r1-distill-qwen-14b | paid + deepseek/deepseek-r1-distill-qwen-14b:free | free deepseek/deepseek-r1-distill-qwen-32b | paid + deepseek/deepseek-r1-distill-qwen-32b:free | free cognitivecomputations/dolphin-mixtral-8x7b | paid + cognitivecomputations/dolphin-mixtral-8x22b | paid cognitivecomputations/dolphin3.0-mistral-24b:free | free cognitivecomputations/dolphin3.0-r1-mistral-24b:free | free eva-unit-01/eva-llama-3.33-70b | paid @@ -82,6 +93,7 @@ export interface IKBotOptions { eva-unit-01/eva-qwen-2.5-72b | paid sao10k/fimbulvetr-11b-v2 | paid alpindale/goliath-120b | paid + google/gemini-2.0-flash-lite-001 | paid google/gemini-2.0-flash-thinking-exp-1219:free | free google/gemini-2.0-flash-thinking-exp:free | free google/gemini-exp-1206:free | free @@ -98,6 +110,11 @@ export interface IKBotOptions { google/gemma-2-27b-it | paid google/gemma-2-9b-it | paid google/gemma-2-9b-it:free | free + google/gemma-3-12b-it:free | free + google/gemma-3-1b-it:free | free + google/gemma-3-27b-it | paid + google/gemma-3-27b-it:free | free + google/gemma-3-4b-it:free | free google/gemma-7b-it | paid google/learnlm-1.5-pro-experimental:free | free google/palm-2-chat-bison | paid @@ -108,6 +125,7 @@ export interface IKBotOptions { infermatic/mn-inferor-12b | paid inflection/inflection-3-pi | paid inflection/inflection-3-productivity | paid + latitudegames/wayfarer-large-70b-llama-3.3 | paid liquid/lfm-3b | paid liquid/lfm-40b | paid liquid/lfm-7b | paid @@ -126,20 +144,25 @@ export interface IKBotOptions { meta-llama/llama-3.1-405b-instruct | paid meta-llama/llama-3.1-70b-instruct | paid meta-llama/llama-3.1-8b-instruct | paid + meta-llama/llama-3.1-8b-instruct:free | free meta-llama/llama-3.2-11b-vision-instruct | paid meta-llama/llama-3.2-11b-vision-instruct:free | free meta-llama/llama-3.2-1b-instruct | paid + meta-llama/llama-3.2-1b-instruct:free | free meta-llama/llama-3.2-3b-instruct | paid + meta-llama/llama-3.2-3b-instruct:free | free meta-llama/llama-3.2-90b-vision-instruct | paid meta-llama/llama-3.3-70b-instruct | paid meta-llama/llama-3.3-70b-instruct:free | free meta-llama/llama-guard-2-8b | paid microsoft/phi-4 | paid + microsoft/phi-4-multimodal-instruct | paid microsoft/phi-3-medium-128k-instruct | paid microsoft/phi-3-medium-128k-instruct:free | free microsoft/phi-3-mini-128k-instruct | paid microsoft/phi-3-mini-128k-instruct:free | free microsoft/phi-3.5-mini-128k-instruct | paid + sophosympatheia/midnight-rose-70b | paid minimax/minimax-01 | paid mistralai/mistral-large | paid mistralai/mistral-large-2407 | paid @@ -155,17 +178,20 @@ export interface IKBotOptions { mistralai/mistral-7b-instruct | paid mistralai/mistral-7b-instruct:free | free mistralai/mistral-7b-instruct-v0.1 | paid + mistralai/mistral-7b-instruct-v0.2 | paid mistralai/mistral-7b-instruct-v0.3 | paid mistralai/mistral-nemo | paid mistralai/mistral-nemo:free | free mistralai/mistral-small-24b-instruct-2501 | paid mistralai/mistral-small-24b-instruct-2501:free | free + mistralai/mistral-small-3.1-24b-instruct | paid mistralai/mixtral-8x22b-instruct | paid mistralai/mixtral-8x7b | paid mistralai/mixtral-8x7b-instruct | paid mistralai/pixtral-12b | paid mistralai/pixtral-large-2411 | paid mistralai/mistral-saba | paid + moonshotai/moonlight-16b-a3b-instruct:free | free gryphe/mythomax-l2-13b | paid gryphe/mythomax-l2-13b:free | free neversleep/llama-3-lumimaid-70b | paid @@ -174,6 +200,7 @@ export interface IKBotOptions { neversleep/llama-3.1-lumimaid-70b | paid neversleep/llama-3.1-lumimaid-8b | paid neversleep/noromaid-20b | paid + nousresearch/deephermes-3-llama-3-8b-preview:free | free nousresearch/nous-hermes-llama2-13b | paid nousresearch/nous-hermes-2-mixtral-8x7b-dpo | paid nousresearch/hermes-3-llama-3.1-405b | paid @@ -181,6 +208,8 @@ export interface IKBotOptions { nousresearch/hermes-2-pro-llama-3-8b | paid nvidia/llama-3.1-nemotron-70b-instruct | paid nvidia/llama-3.1-nemotron-70b-instruct:free | free + open-r1/olympiccoder-32b:free | free + open-r1/olympiccoder-7b:free | free openai/chatgpt-4o-latest | paid openai/gpt-3.5-turbo | paid openai/gpt-3.5-turbo-0613 | paid @@ -195,13 +224,16 @@ export interface IKBotOptions { openai/gpt-4-turbo | paid openai/gpt-4-1106-preview | paid openai/gpt-4-turbo-preview | paid + openai/gpt-4.5-preview | paid openai/gpt-4o | paid openai/gpt-4o-2024-05-13 | paid openai/gpt-4o-2024-08-06 | paid openai/gpt-4o-2024-11-20 | paid openai/gpt-4o:extended | paid + openai/gpt-4o-search-preview | paid openai/gpt-4o-mini | paid openai/gpt-4o-mini-2024-07-18 | paid + openai/gpt-4o-mini-search-preview | paid openai/o1 | paid openai/o1-mini | paid openai/o1-mini-2024-09-12 | paid @@ -211,27 +243,41 @@ export interface IKBotOptions { openai/o3-mini-high | paid openchat/openchat-7b | paid openchat/openchat-7b:free | free - perplexity/llama-3.1-sonar-huge-128k-online | paid + teknium/openhermes-2.5-mistral-7b | paid perplexity/llama-3.1-sonar-large-128k-chat | paid perplexity/llama-3.1-sonar-large-128k-online | paid perplexity/llama-3.1-sonar-small-128k-chat | paid perplexity/llama-3.1-sonar-small-128k-online | paid + perplexity/r1-1776 | paid perplexity/sonar | paid + perplexity/sonar-deep-research | paid + perplexity/sonar-pro | paid perplexity/sonar-reasoning | paid + perplexity/sonar-reasoning-pro | paid pygmalionai/mythalion-13b | paid qwen/qwen-2-72b-instruct | paid - qwen/qvq-72b-preview | paid - qwen/qwen-vl-plus:free | free + qwen/qwen-2-7b-instruct | paid + qwen/qwen-2-7b-instruct:free | free + qwen/qwen-vl-max | paid + qwen/qwen-vl-plus | paid qwen/qwen-max | paid qwen/qwen-plus | paid qwen/qwen-turbo | paid + qwen/qwen2.5-32b-instruct | paid + qwen/qwen2.5-vl-72b-instruct | paid qwen/qwen2.5-vl-72b-instruct:free | free + qwen/qwen-2.5-vl-72b-instruct | paid + qwen/qwen-2.5-vl-7b-instruct | paid + qwen/qwq-32b | paid + qwen/qwq-32b:free | free qwen/qwq-32b-preview | paid - qwen/qwen-2-vl-72b-instruct | paid - qwen/qwen-2-vl-7b-instruct | paid + qwen/qwq-32b-preview:free | free qwen/qwen-2.5-72b-instruct | paid + qwen/qwen-2.5-72b-instruct:free | free qwen/qwen-2.5-7b-instruct | paid qwen/qwen-2.5-coder-32b-instruct | paid + qwen/qwen-2.5-coder-32b-instruct:free | free + rekaai/reka-flash-3:free | free undi95/remm-slerp-l2-13b | paid thedrummer/rocinante-12b | paid sophosympatheia/rogue-rose-103b-v0.2:free | free @@ -241,6 +287,10 @@ export interface IKBotOptions { sao10k/l3.1-euryale-70b | paid sao10k/l3.3-euryale-70b | paid raifle/sorcererlm-8x22b | paid + steelskull/l3.3-electra-r1-70b | paid + tokyotech-llm/llama-3.1-swallow-70b-instruct-v0.3 | paid + thedrummer/anubis-pro-105b-v1 | paid + thedrummer/skyfall-36b-v2 | paid undi95/toppy-m-7b | paid undi95/toppy-m-7b:free | free thedrummer/unslopnemo-12b | paid @@ -272,6 +322,8 @@ export interface IKBotOptions { gpt-4-turbo gpt-4-turbo-2024-04-09 gpt-4-turbo-preview + gpt-4.5-preview + gpt-4.5-preview-2025-02-27 gpt-4o gpt-4o-2024-05-13 gpt-4o-2024-08-06 @@ -285,13 +337,21 @@ export interface IKBotOptions { gpt-4o-mini-audio-preview-2024-12-17 gpt-4o-mini-realtime-preview gpt-4o-mini-realtime-preview-2024-12-17 + gpt-4o-mini-search-preview + gpt-4o-mini-search-preview-2025-03-11 gpt-4o-realtime-preview gpt-4o-realtime-preview-2024-10-01 gpt-4o-realtime-preview-2024-12-17 + gpt-4o-search-preview + gpt-4o-search-preview-2025-03-11 + o1 + o1-2024-12-17 o1-mini o1-mini-2024-09-12 o1-preview o1-preview-2024-09-12 + o3-mini + o3-mini-2025-01-31 omni-moderation-2024-09-26 omni-moderation-latest text-embedding-3-large diff --git a/packages/ai-tools/history.json b/packages/ai-tools/history.json deleted file mode 100644 index c6e3857e..00000000 --- a/packages/ai-tools/history.json +++ /dev/null @@ -1,6233 +0,0 @@ -[ - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = join(target, file.path)\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : Adjust all yargs code as instructed\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\nexport const ListFilesSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n});\\n\\nexport const RemoveFileSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n});\\n\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport * as yargs from 'yargs';\\nimport { commands } from './commands';\\n\\nasync function main() {\\n const argv = await commands(yargs).argv;\\n}\\n\\nmain().catch(console.error);\\n\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\n\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { ListFilesSchema, RemoveFileSchema } from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n ListFilesSchema,\\n RemoveFileSchema\\n ], 'src/zod_types.ts');\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .strict()\\n .help();\\n};\\n\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T12:17:26.611Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = join(target, file.path)\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : Adjust all yargs code as instructed\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nA command-line interface and library for LLM (Language Model) tools with filesystem operations support.\\n\\n## Setup\\n\\n```bash\\n# Install dependencies\\nnpm install\\n\\n# Build the project\\nnpm run build\\n\\n# Create symlink for global usage\\nnpm link\\n```\\n\\n## Configuration\\n\\nThe application uses configuration files for API keys and settings. Create a configuration file with the following structure:\\n\\n```json\\n{\\n \\\"openai\\\": {\\n \\\"key\\\": \\\"your-openai-key\\\"\\n }\\n}\\n```\\n\\nThe configuration can be loaded using the `env_key` parameter or environment variables.\\n\\n## Commands\\n\\n### Generate TypeScript Types\\n\\nGenerate TypeScript interfaces from Zod schemas:\\n\\n```bash\\nllm-tools types\\n```\\n\\n## Library Functions\\n\\n### Filesystem Tools\\n\\nThe package provides LLM tools for filesystem operations:\\n\\n#### List Files\\n```typescript\\ninterface ListFilesParams {\\n directory: string; // Directory path to list files from\\n pattern?: string; // Optional glob pattern for filtering files\\n}\\n```\\n\\n#### Remove File\\n```typescript\\ninterface RemoveFileParams {\\n path: string; // Path of the file to remove\\n}\\n```\\n\\n### Development\\n\\n```bash\\n# Run in development mode\\nnpm run dev\\n\\n# Generate TypeScript interfaces\\nnpm run types\\n```\\n\\n## Project Structure\\n\\n```\\nsrc/\\n├── index.ts # Logger setup\\n├── main.ts # CLI entry point\\n├── constants.ts # Constants definition\\n├── zod_schemas.ts # Zod schema definitions\\n├── commands/\\n│ ├── index.ts # Command registration\\n│ └── types.ts # Types generation command\\n└── lib/\\n └── tools/\\n └── fs.ts # Filesystem tools implementation\\n```\\n\\n## Dependencies\\n\\n- tslog: Logging functionality\\n- yargs: CLI argument parsing\\n- zod: Schema validation\\n- axios: HTTP client\\n- openai: OpenAI API integration\\n- @plastichub packages: Filesystem and utility functions\\n\\n## License\\n\\nMIT\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\nexport const ListFilesSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n});\\n\\nexport const RemoveFileSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n});\\n\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport * as yargs from 'yargs';\\nimport { commands } from './commands';\\nimport { logger } from './';\\n\\nasync function main() {\\n try {\\n const argv = await commands(yargs).argv;\\n } catch (error) {\\n logger.error('Error executing command:', error);\\n process.exit(1);\\n }\\n}\\n\\nmain();\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\n\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { ListFilesSchema, RemoveFileSchema } from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n ListFilesSchema,\\n RemoveFileSchema\\n ], 'src/zod_types.ts');\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons';\\nimport { logger } from '../';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .option('env_key', {\\n type: 'string',\\n description: 'Environment configuration key'\\n })\\n .middleware([(argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any;\\n if (!config) {\\n logger.warn('No config found!');\\n return;\\n }\\n return config;\\n }])\\n .strict()\\n .help();\\n};\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T12:17:59.604Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = join(target, file.path)\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : fix src/main.ts : import * as yargs from 'yargs'; : Type originates at this import. A namespace-style import cannot be called or constructed, and will cause a failure at runtime. Consider using a default import or import require here instead.\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nA command-line interface and library for LLM (Language Model) tools with filesystem operations support.\\n\\n## Setup\\n\\n```bash\\n# Install dependencies\\nnpm install\\n\\n# Build the project\\nnpm run build\\n\\n# Create symlink for global usage\\nnpm link\\n```\\n\\n## Configuration\\n\\nThe application uses configuration files for API keys and settings. Configuration can be loaded in multiple ways:\\n\\n1. Using `--env_key` parameter\\n2. Environment variables (e.g., OPENAI_API_KEY)\\n3. Configuration file\\n\\nExample configuration file:\\n\\n```json\\n{\\n \\\"openai\\\": {\\n \\\"key\\\": \\\"your-openai-key\\\"\\n }\\n}\\n```\\n\\n## Commands\\n\\n### Generate TypeScript Types\\n\\nGenerate TypeScript interfaces from Zod schemas:\\n\\n```bash\\nllm-tools types\\n```\\n\\n## Library Functions\\n\\n### Filesystem Tools\\n\\nThe package provides two main LLM tools for filesystem operations:\\n\\n#### List Files\\n```typescript\\ninterface ListFilesParams {\\n directory: string; // Directory path to list files from\\n pattern?: string; // Optional glob pattern for filtering files\\n}\\n```\\n\\nExample usage in LLM tools:\\n```typescript\\nawait list_files({\\n directory: './src',\\n pattern: '**/*.ts'\\n});\\n```\\n\\n#### Remove File\\n```typescript\\ninterface RemoveFileParams {\\n path: string; // Path of the file to remove\\n}\\n```\\n\\nExample usage in LLM tools:\\n```typescript\\nawait remove_file({\\n path: './temp/file.txt'\\n});\\n```\\n\\n## Development\\n\\n```bash\\n# Run in development mode\\nnpm run dev\\n\\n# Generate TypeScript interfaces\\nnpm run types\\n```\\n\\n## Project Structure\\n\\n```\\nsrc/\\n├── index.ts # Logger setup using tslog\\n├── main.ts # CLI entry point with yargs\\n├── constants.ts # Constants and logger name\\n├── zod_schemas.ts # Zod schema definitions\\n├── commands/\\n│ ├── index.ts # Command registration\\n│ └── types.ts # Types generation command\\n└── lib/\\n └── tools/\\n └── fs.ts # Filesystem tools implementation\\n```\\n\\n## Key Features\\n\\n- **Type Safety**: Uses Zod for schema validation and TypeScript interface generation\\n- **Filesystem Operations**: Built-in tools for file listing and removal\\n- **Logging**: Structured logging with tslog\\n- **Configuration Management**: Flexible configuration loading\\n- **OpenAI Integration**: Built-in support for OpenAI API\\n\\n## Dependencies\\n\\n### Core Dependencies\\n- tslog: Type-safe logging\\n- yargs: Command-line argument parsing\\n- zod: Schema validation and type generation\\n- axios: HTTP client\\n- openai: OpenAI API integration\\n\\n### Plastichub Dependencies\\n- @plastichub/core: Core utilities\\n- @plastichub/fs: Filesystem operations\\n- @plastichub/osr-commons: Common utilities\\n- @plastichub/osr-log: Logging utilities\\n\\n## Development Dependencies\\n- TypeScript and related type definitions\\n- ts-node for development execution\\n\\n## License\\n\\nMIT\\n\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\nexport const ListFilesSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n});\\n\\nexport const RemoveFileSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n});\\n\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport * as yargs from 'yargs';\\nimport { commands } from './commands';\\nimport { logger } from './';\\n\\nasync function main() {\\n try {\\n const argv = await commands(yargs).argv;\\n } catch (error) {\\n logger.error('Error executing command:', error);\\n process.exit(1);\\n }\\n}\\n\\nmain();\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\n\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { ListFilesSchema, RemoveFileSchema } from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n ListFilesSchema,\\n RemoveFileSchema\\n ], 'src/zod_types.ts');\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons';\\nimport { logger } from '../';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .option('env_key', {\\n type: 'string',\\n description: 'Environment configuration key'\\n })\\n .middleware([(argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any;\\n if (!config) {\\n logger.warn('No config found!');\\n return;\\n }\\n return config;\\n }])\\n .strict()\\n .help();\\n};\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T12:19:50.719Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = join(target, file.path)\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : add another tool in tools/npm : build_project (using pnpm build), return the output & errors\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nA command-line interface and library for LLM (Language Model) tools with filesystem operations support.\\n\\n## Installation\\n\\n```bash\\n# Clone the repository\\ngit clone [repository-url]\\ncd llm-tools-cli\\n\\n# Install dependencies\\nnpm install\\n\\n# Build the project\\nnpm run build\\n\\n# Create symlink for global usage\\nnpm link\\n```\\n\\n## Configuration\\n\\nConfiguration is managed through multiple sources, in order of precedence:\\n\\n1. Command line arguments (--env_key)\\n2. Environment variables (OPENAI_API_KEY)\\n3. Configuration file\\n\\nCreate a configuration file (e.g., config.json):\\n\\n```json\\n{\\n \\\"openai\\\": {\\n \\\"key\\\": \\\"your-openai-key\\\"\\n }\\n}\\n```\\n\\n## Available Commands\\n\\n### Generate TypeScript Types\\nGenerates TypeScript interfaces from all Zod schemas in the project:\\n\\n```bash\\nllm-tools types\\n```\\n\\n### Command Options\\n\\nAll commands support these global options:\\n\\n```bash\\n--env_key Specify environment configuration key\\n--help Show help information\\n```\\n\\n## Library Functions\\n\\n### Filesystem Operations\\n\\n#### List Files Tool\\n```typescript\\ninterface ListFilesParams {\\n directory: string; // Directory path to list files from\\n pattern?: string; // Optional glob pattern for filtering files\\n}\\n```\\n\\nUsage:\\n```typescript\\nimport { tools } from './lib/tools/fs';\\n\\nconst fsTools = tools('./target-directory');\\nconst listFiles = fsTools.find(t => t.function.name === 'list_files');\\nawait listFiles.function.function({\\n directory: './src',\\n pattern: '**/*.ts'\\n});\\n```\\n\\n#### Remove File Tool\\n```typescript\\ninterface RemoveFileParams {\\n path: string; // Path of the file to remove\\n}\\n```\\n\\nUsage:\\n```typescript\\nconst removeFile = fsTools.find(t => t.function.name === 'remove_file');\\nawait removeFile.function.function({\\n path: './temp/file.txt'\\n});\\n```\\n\\n## Project Structure\\n\\n```\\nsrc/\\n├── index.ts # Logger setup and exports\\n├── main.ts # CLI entry point\\n├── constants.ts # Project constants\\n├── zod_schemas.ts # Zod schema definitions\\n├── commands/\\n│ ├── index.ts # Command registration\\n│ └── types.ts # Types generation command\\n└── lib/\\n └── tools/\\n └── fs.ts # Filesystem tools implementation\\n```\\n\\n## Development\\n\\n```bash\\n# Run in development mode\\nnpm run dev\\n\\n# Generate TypeScript types\\nnpm run types\\n\\n# Build for production\\nnpm run build\\n```\\n\\n## Key Features\\n\\n- **Type Safety**: Zod schemas with TypeScript interface generation\\n- **Filesystem Operations**: Tools for file listing and removal\\n- **Logging**: Structured logging with tslog\\n- **Configuration Management**: Flexible config loading system\\n- **OpenAI Integration**: Ready for OpenAI API usage\\n\\n## Dependencies\\n\\n### Main Dependencies\\n- tslog: Type-safe logging\\n- yargs: CLI argument parsing\\n- zod: Schema validation\\n- axios: HTTP client\\n- openai: OpenAI API client\\n\\n### Plastichub Dependencies\\n- @plastichub/core: Core utilities\\n- @plastichub/fs: Filesystem operations\\n- @plastichub/osr-commons: Common utilities\\n- @plastichub/osr-log: Logging utilities\\n\\n## License\\n\\nMIT\\n\"\n },\n {\n \"path\": \"src\\\\zod_types.ts\",\n \"content\": \"export interface IOptions {\\n /** Directory path to list files from */\\n directory: string;\\n /** Glob pattern for filtering files */\\n pattern?: string | undefined;\\n}\\nexport interface IOptions {\\n /** Path of the file to remove */\\n path: string;\\n}\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\nexport const ListFilesSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n});\\n\\nexport const RemoveFileSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n});\\n\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport yargs from 'yargs';\\nimport { commands } from './commands';\\nimport { logger } from './';\\n\\nasync function main() {\\n try {\\n const argv = await commands(yargs).argv;\\n } catch (error) {\\n logger.error('Error executing command:', error);\\n process.exit(1);\\n }\\n}\\n\\nmain();\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\n\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { ListFilesSchema, RemoveFileSchema } from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n ListFilesSchema,\\n RemoveFileSchema\\n ], 'src/zod_types.ts');\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons';\\nimport { logger } from '../';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .option('env_key', {\\n type: 'string',\\n description: 'Environment configuration key'\\n })\\n .middleware([(argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any;\\n if (!config) {\\n logger.warn('No config found!');\\n return;\\n }\\n return config;\\n }])\\n .strict()\\n .help();\\n};\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T12:22:23.904Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = join(target, file.path)\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : export all tools as object literal in src/index.ts\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nA command-line interface and library for LLM (Language Model) tools with filesystem operations support.\\n\\n## Installation\\n\\n```bash\\n# Clone the repository\\ngit clone [repository-url]\\ncd llm-tools-cli\\n\\n# Install dependencies using pnpm\\npnpm install\\n\\n# Build the project\\npnpm build\\n\\n# Create symlink for global usage\\npnpm link\\n```\\n\\n## Configuration\\n\\nConfiguration is managed through multiple sources, in order of precedence:\\n\\n1. Command line arguments (--env_key)\\n2. Environment variables (OPENAI_API_KEY)\\n3. Configuration file\\n\\nCreate a configuration file (e.g., config.json):\\n\\n```json\\n{\\n \\\"openai\\\": {\\n \\\"key\\\": \\\"your-openai-key\\\"\\n }\\n}\\n```\\n\\n## Available Commands\\n\\n### Generate TypeScript Types\\nGenerates TypeScript interfaces from all Zod schemas in the project:\\n\\n```bash\\nllm-tools types\\n```\\n\\n### Command Options\\n\\nAll commands support these global options:\\n\\n```bash\\n--env_key Specify environment configuration key\\n--help Show help information\\n```\\n\\n## Library Functions\\n\\n### Filesystem Operations\\n\\n#### List Files Tool\\n```typescript\\ninterface ListFilesParams {\\n directory: string; // Directory path to list files from\\n pattern?: string; // Optional glob pattern for filtering files\\n}\\n```\\n\\nUsage:\\n```typescript\\nimport { tools } from './lib/tools/fs';\\n\\nconst fsTools = tools('./target-directory');\\nconst listFiles = fsTools.find(t => t.function.name === 'list_files');\\nawait listFiles.function.function({\\n directory: './src',\\n pattern: '**/*.ts'\\n});\\n```\\n\\n#### Remove File Tool\\n```typescript\\ninterface RemoveFileParams {\\n path: string; // Path of the file to remove\\n}\\n```\\n\\nUsage:\\n```typescript\\nconst removeFile = fsTools.find(t => t.function.name === 'remove_file');\\nawait removeFile.function.function({\\n path: './temp/file.txt'\\n});\\n```\\n\\n### NPM Tools\\n\\n#### Build Project Tool\\nBuilds the project using pnpm build command and returns the build output and any errors.\\n\\nUsage:\\n```typescript\\nimport { tools } from './lib/tools/npm';\\n\\nconst npmTools = tools('./project-directory');\\nconst buildProject = npmTools.find(t => t.function.name === 'build_project');\\nconst result = await buildProject.function.function();\\n// Returns: { success: boolean, output: string | null, error: string | null }\\n```\\n\\n## Project Structure\\n\\n```\\nsrc/\\n├── index.ts # Logger setup and exports\\n├── main.ts # CLI entry point\\n├── constants.ts # Project constants\\n├── zod_schemas.ts # Zod schema definitions\\n├── commands/\\n│ ├── index.ts # Command registration\\n│ └── types.ts # Types generation command\\n└── lib/\\n └── tools/\\n ├── fs.ts # Filesystem tools implementation\\n └── npm.ts # NPM tools implementation\\n```\\n\\n## Development\\n\\n```bash\\n# Run in development mode\\npnpm dev\\n\\n# Generate TypeScript types\\npnpm types\\n\\n# Build for production\\npnpm build\\n```\\n\\n## Key Features\\n\\n- **Type Safety**: Zod schemas with TypeScript interface generation\\n- **Filesystem Operations**: Tools for file listing and removal\\n- **NPM Operations**: Project building tools\\n- **Logging**: Structured logging with tslog\\n- **Configuration Management**: Flexible config loading system\\n- **OpenAI Integration**: Ready for OpenAI API usage\\n\\n## Dependencies\\n\\n### Main Dependencies\\n- tslog: Type-safe logging\\n- yargs: CLI argument parsing\\n- zod: Schema validation\\n- axios: HTTP client\\n- openai: OpenAI API client\\n\\n### Plastichub Dependencies\\n- @plastichub/core: Core utilities\\n- @plastichub/fs: Filesystem operations\\n- @plastichub/osr-commons: Common utilities\\n- @plastichub/osr-log: Logging utilities\\n\\n## License\\n\\nMIT\\n\"\n },\n {\n \"path\": \"src\\\\zod_types.ts\",\n \"content\": \"export interface IOptions {\\n /** Directory path to list files from */\\n directory: string;\\n /** Glob pattern for filtering files */\\n pattern?: string | undefined;\\n}\\nexport interface IOptions {\\n /** Path of the file to remove */\\n path: string;\\n}\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\nexport const ListFilesSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n});\\n\\nexport const RemoveFileSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n});\\n\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport yargs from 'yargs';\\nimport { commands } from './commands';\\nimport { logger } from './';\\n\\nasync function main() {\\n try {\\n const argv = await commands(yargs).argv;\\n } catch (error) {\\n logger.error('Error executing command:', error);\\n process.exit(1);\\n }\\n}\\n\\nmain();\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\n\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\npm.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'build_project',\\n description: 'Build project using pnpm build command',\\n parameters: {\\n type: 'object',\\n properties: {},\\n required: []\\n },\\n function: async () => {\\n try {\\n logger.debug(`Tool::BuildProject Building project at ${target}`);\\n const { stdout, stderr } = await execAsync('pnpm build', {\\n cwd: target\\n });\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error : any) {\\n logger.error('Error building project', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { ListFilesSchema, RemoveFileSchema } from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n ListFilesSchema,\\n RemoveFileSchema\\n ], 'src/zod_types.ts');\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons';\\nimport { logger } from '../';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .option('env_key', {\\n type: 'string',\\n description: 'Environment configuration key'\\n })\\n .middleware([(argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any;\\n if (!config) {\\n logger.warn('No config found!');\\n return;\\n }\\n return config;\\n }])\\n .strict()\\n .help();\\n};\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T12:25:33.495Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = join(target, file.path)\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : export all tools as object literal in src/tools.ts\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nA command-line interface and library for LLM (Language Model) tools with filesystem operations support.\\n\\n## Installation\\n\\n```bash\\n# Install dependencies\\npnpm install\\n\\n# Build the project\\npnpm build\\n\\n# Generate TypeScript types\\npnpm types\\n```\\n\\n## Configuration\\n\\nConfiguration is loaded from multiple sources in this order:\\n1. Command line arguments (--env_key)\\n2. Environment variables (OPENAI_API_KEY)\\n3. Configuration file\\n\\nConfig file example:\\n```json\\n{\\n \\\"openai\\\": {\\n \\\"key\\\": \\\"your-openai-key\\\"\\n }\\n}\\n```\\n\\n## Commands\\n\\n### Generate TypeScript Types\\n```bash\\nllm-tools types\\n```\\nGenerates TypeScript interfaces from all Zod schemas in the project.\\n\\n### Global Options\\n```bash\\n--env_key Environment configuration key\\n--help Show command help\\n```\\n\\n## Library Usage\\n\\n### Filesystem Tools\\n\\n```typescript\\nimport { tools as fsTools } from './lib/tools/fs';\\n\\n// Initialize tools with target directory\\nconst tools = fsTools('./target-directory');\\n\\n// List Files\\nconst listFiles = tools.find(t => t.function.name === 'list_files');\\nawait listFiles.function.function({\\n directory: './src',\\n pattern: '**/*.ts'\\n});\\n\\n// Remove File\\nconst removeFile = tools.find(t => t.function.name === 'remove_file');\\nawait removeFile.function.function({\\n path: './temp/file.txt'\\n});\\n```\\n\\n### NPM Tools\\n\\n```typescript\\nimport { tools as npmTools } from './lib/tools/npm';\\n\\n// Initialize tools with target directory\\nconst tools = npmTools('./project-directory');\\n\\n// Build Project\\nconst buildProject = tools.find(t => t.function.name === 'build_project');\\nconst result = await buildProject.function.function();\\n// Returns: { success: boolean, output: string | null, error: string | null }\\n```\\n\\n## Project Structure\\n\\n```\\nsrc/\\n├── index.ts # Logger setup and exports\\n├── main.ts # CLI entry point\\n├── constants.ts # Project constants\\n├── zod_schemas.ts # Zod schema definitions\\n├── commands/\\n│ ├── index.ts # Command registration\\n│ └── types.ts # Types generation command\\n└── lib/\\n └── tools/\\n ├── fs.ts # Filesystem tools implementation\\n └── npm.ts # NPM tools implementation\\n```\\n\\n## Key Features\\n\\n- Type-safe CLI with Zod schemas and TypeScript\\n- File operations (list, remove)\\n- NPM project operations\\n- Built-in logging with tslog\\n- Custom configuration system\\n- OpenAI integration support\\n\\n## Dependencies\\n\\n- tslog: Type-safe logging\\n- yargs: CLI argument parsing\\n- zod: Schema validation\\n- axios: HTTP client\\n- openai: OpenAI API client\\n- @plastichub packages: Core utilities, filesystem operations, and logging\\n\\n## Development\\n\\n```bash\\n# Run in development mode\\npnpm dev\\n\\n# Generate types\\npnpm types\\n\\n# Build project\\npnpm build\\n```\\n\\n## Available Tools\\n\\n### Filesystem Tools\\n\\n#### list_files\\nLists files in a directory with optional pattern matching.\\n```typescript\\ninterface ListFilesParams {\\n directory: string; // Directory to list files from\\n pattern?: string; // Optional glob pattern\\n}\\n```\\n\\n#### remove_file\\nRemoves a file at the specified path.\\n```typescript\\ninterface RemoveFileParams {\\n path: string; // Path to file to remove\\n}\\n```\\n\\n### NPM Tools\\n\\n#### build_project\\nBuilds project using pnpm build command.\\n```typescript\\ninterface BuildResult {\\n success: boolean;\\n output: string | null;\\n error: string | null;\\n}\\n```\\n\\n## License\\n\\nMIT\"\n },\n {\n \"path\": \"src\\\\zod_types.ts\",\n \"content\": \"export interface IOptions {\\n /** Directory path to list files from */\\n directory: string;\\n /** Glob pattern for filtering files */\\n pattern?: string | undefined;\\n}\\nexport interface IOptions {\\n /** Path of the file to remove */\\n path: string;\\n}\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\nexport const ListFilesSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n});\\n\\nexport const RemoveFileSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n});\\n\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport yargs from 'yargs';\\nimport { commands } from './commands';\\nimport { logger } from './';\\n\\nasync function main() {\\n try {\\n const argv = await commands(yargs).argv;\\n } catch (error) {\\n logger.error('Error executing command:', error);\\n process.exit(1);\\n }\\n}\\n\\nmain();\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\npm.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'build_project',\\n description: 'Build project using pnpm build command',\\n parameters: {\\n type: 'object',\\n properties: {},\\n required: []\\n },\\n function: async () => {\\n try {\\n logger.debug(`Tool::BuildProject Building project at ${target}`);\\n const { stdout, stderr } = await execAsync('pnpm build', {\\n cwd: target\\n });\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error : any) {\\n logger.error('Error building project', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { ListFilesSchema, RemoveFileSchema } from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n ListFilesSchema,\\n RemoveFileSchema\\n ], 'src/zod_types.ts');\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons';\\nimport { logger } from '../';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .option('env_key', {\\n type: 'string',\\n description: 'Environment configuration key'\\n })\\n .middleware([(argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any;\\n if (!config) {\\n logger.warn('No config found!');\\n return;\\n }\\n return config;\\n }])\\n .strict()\\n .help();\\n};\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T12:27:43.323Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = join(target, file.path)\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : Add another command to list all tools\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nA command-line interface and library for LLM (Language Model) tools with filesystem operations support.\\n\\n## Installation\\n\\n```bash\\n# Install dependencies\\npnpm install\\n\\n# Build the project\\npnpm build\\n\\n# Generate TypeScript types\\npnpm types\\n```\\n\\n## Configuration\\n\\nConfiguration is loaded from multiple sources in this order:\\n1. Command line arguments (--env_key)\\n2. Environment variables (OPENAI_API_KEY)\\n3. Configuration file\\n\\nConfig file example:\\n```json\\n{\\n \\\"openai\\\": {\\n \\\"key\\\": \\\"your-openai-key\\\"\\n }\\n}\\n```\\n\\n## Command Line Usage\\n\\n### Generate TypeScript Types\\n```bash\\nllm-tools types\\n```\\nGenerates TypeScript interfaces from Zod schemas in the project.\\n\\n### Global Options\\n```bash\\n--env_key Environment configuration key\\n--help Show help information\\n```\\n\\n## Library Usage\\n\\n### Import Tools\\n\\n```typescript\\nimport { tools } from './tools';\\n\\n// Initialize tools with target directory\\nconst fsTools = tools.fs('./target-directory');\\nconst npmTools = tools.npm('./project-directory');\\n```\\n\\n### Filesystem Tools\\n\\n```typescript\\n// List Files\\nconst listFiles = fsTools.find(t => t.function.name === 'list_files');\\nawait listFiles.function.function({\\n directory: './src',\\n pattern: '**/*.ts'\\n});\\n\\n// Remove File\\nconst removeFile = fsTools.find(t => t.function.name === 'remove_file');\\nawait removeFile.function.function({\\n path: './temp/file.txt'\\n});\\n```\\n\\n### NPM Tools\\n\\n```typescript\\n// Build Project\\nconst buildProject = npmTools.find(t => t.function.name === 'build_project');\\nconst result = await buildProject.function.function();\\n// Returns: { success: boolean, output: string | null, error: string | null }\\n```\\n\\n## Project Structure\\n\\n```\\nsrc/\\n├── index.ts # Logger setup and exports\\n├── main.ts # CLI entry point\\n├── constants.ts # Project constants\\n├── tools.ts # Tools exports\\n├── zod_schemas.ts # Zod schema definitions\\n├── commands/\\n│ ├── index.ts # Command registration\\n│ └── types.ts # Types generation command\\n└── lib/\\n └── tools/\\n ├── fs.ts # Filesystem tools implementation\\n └── npm.ts # NPM tools implementation\\n```\\n\\n## Available Tools\\n\\n### Filesystem Tools\\n\\n#### list_files\\nLists files in a directory with optional pattern matching.\\n```typescript\\ninterface ListFilesParams {\\n directory: string; // Directory to list files from\\n pattern?: string; // Optional glob pattern\\n}\\n```\\n\\n#### remove_file\\nRemoves a file at the specified path.\\n```typescript\\ninterface RemoveFileParams {\\n path: string; // Path to file to remove\\n}\\n```\\n\\n### NPM Tools\\n\\n#### build_project\\nBuilds project using pnpm build command.\\n```typescript\\ninterface BuildResult {\\n success: boolean;\\n output: string | null;\\n error: string | null;\\n}\\n```\\n\\n## Development\\n\\n```bash\\n# Run in development mode\\npnpm dev\\n\\n# Generate types\\npnpm types\\n\\n# Build project\\npnpm build\\n```\\n\\n## Key Features\\n\\n- Type-safe CLI with Zod schemas and TypeScript\\n- File operations (list, remove)\\n- NPM project operations\\n- Built-in logging with tslog\\n- Custom configuration system\\n- OpenAI integration support\\n\\n## Dependencies\\n\\n- tslog: Type-safe logging\\n- yargs: CLI argument parsing\\n- zod: Schema validation\\n- axios: HTTP client\\n- openai: OpenAI API client\\n- @plastichub packages: Core utilities, filesystem operations, and logging\\n\\n## License\\n\\nMIT\"\n },\n {\n \"path\": \"src\\\\zod_types.ts\",\n \"content\": \"export interface IOptions {\\n /** Directory path to list files from */\\n directory: string;\\n /** Glob pattern for filtering files */\\n pattern?: string | undefined;\\n}\\nexport interface IOptions {\\n /** Path of the file to remove */\\n path: string;\\n}\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\nexport const ListFilesSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n});\\n\\nexport const RemoveFileSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n});\\n\"\n },\n {\n \"path\": \"src\\\\tools.ts\",\n \"content\": \"import { tools as fsTools } from './lib/tools/fs';\\nimport { tools as npmTools } from './lib/tools/npm';\\n\\nexport const tools = {\\n fs: fsTools,\\n npm: npmTools\\n};\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport yargs from 'yargs';\\nimport { commands } from './commands';\\nimport { logger } from './';\\n\\nasync function main() {\\n try {\\n const argv = await commands(yargs).argv;\\n } catch (error) {\\n logger.error('Error executing command:', error);\\n process.exit(1);\\n }\\n}\\n\\nmain();\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\npm.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'build_project',\\n description: 'Build project using pnpm build command',\\n parameters: {\\n type: 'object',\\n properties: {},\\n required: []\\n },\\n function: async () => {\\n try {\\n logger.debug(`Tool::BuildProject Building project at ${target}`);\\n const { stdout, stderr } = await execAsync('pnpm build', {\\n cwd: target\\n });\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error : any) {\\n logger.error('Error building project', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { ListFilesSchema, RemoveFileSchema } from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n ListFilesSchema,\\n RemoveFileSchema\\n ], 'src/zod_types.ts');\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons';\\nimport { logger } from '../';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .option('env_key', {\\n type: 'string',\\n description: 'Environment configuration key'\\n })\\n .middleware([(argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any;\\n if (!config) {\\n logger.warn('No config found!');\\n return;\\n }\\n return config;\\n }])\\n .strict()\\n .help();\\n};\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T12:28:49.445Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = join(target, file.path)\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : Add another command to invoke a tool, eg: --tools=fs --function=remove_file --target=cwd\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\",\\n \\\"list\\\": \\\"ts-node src/main.ts list\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nA command-line interface and library for LLM (Language Model) tools with filesystem operations support.\\n\\n## Setup\\n\\n1. Clone the repository\\n2. Install dependencies:\\n```bash\\npnpm install\\n```\\n\\n3. Build the project:\\n```bash\\npnpm build\\n```\\n\\n4. Link the CLI (optional):\\n```bash\\npnpm link\\n```\\n\\n## Configuration\\n\\nConfiguration is loaded from multiple sources in this order:\\n1. Command line arguments (--env_key)\\n2. Environment variables (OPENAI_API_KEY)\\n3. Configuration file\\n\\nConfig file example:\\n```json\\n{\\n \\\"openai\\\": {\\n \\\"key\\\": \\\"your-openai-key\\\"\\n }\\n}\\n```\\n\\n## Command Line Usage\\n\\n### List Available Tools\\n```bash\\nllm-tools list\\n```\\nDisplays all available tools and their descriptions.\\n\\n### Generate TypeScript Types\\n```bash\\nllm-tools types\\n```\\nGenerates TypeScript interfaces from Zod schemas in the project.\\n\\n### Global Options\\n```bash\\n--env_key Environment configuration key\\n--help Show help information\\n```\\n\\n## Library Usage\\n\\n### Import Tools\\n\\n```typescript\\nimport { tools } from './tools';\\n\\n// Initialize tools with target directory\\nconst fsTools = tools.fs('./target-directory');\\nconst npmTools = tools.npm('./project-directory');\\n```\\n\\n### Filesystem Tools\\n\\n```typescript\\n// List Files\\nconst listFiles = fsTools.find(t => t.function.name === 'list_files');\\nawait listFiles.function.function({\\n directory: './src',\\n pattern: '**/*.ts'\\n});\\n\\n// Remove File\\nconst removeFile = fsTools.find(t => t.function.name === 'remove_file');\\nawait removeFile.function.function({\\n path: './temp/file.txt'\\n});\\n```\\n\\n### NPM Tools\\n\\n```typescript\\n// Build Project\\nconst buildProject = npmTools.find(t => t.function.name === 'build_project');\\nconst result = await buildProject.function.function();\\n// Returns: { success: boolean, output: string | null, error: string | null }\\n```\\n\\n## Project Structure\\n\\n```\\nsrc/\\n├── index.ts # Logger setup and exports\\n├── main.ts # CLI entry point\\n├── constants.ts # Project constants\\n├── tools.ts # Tools exports\\n├── zod_schemas.ts # Zod schema definitions\\n├── commands/\\n│ ├── index.ts # Command registration\\n│ ├── list.ts # List tools command\\n│ └── types.ts # Types generation command\\n└── lib/\\n └── tools/\\n ├── fs.ts # Filesystem tools implementation\\n └── npm.ts # NPM tools implementation\\n```\\n\\n## Available Tools\\n\\n### Filesystem Tools\\n\\n#### list_files\\nLists files in a directory with optional pattern matching.\\n```typescript\\ninterface ListFilesParams {\\n directory: string; // Directory to list files from\\n pattern?: string; // Optional glob pattern\\n}\\n```\\n\\n#### remove_file\\nRemoves a file at the specified path.\\n```typescript\\ninterface RemoveFileParams {\\n path: string; // Path to file to remove\\n}\\n```\\n\\n### NPM Tools\\n\\n#### build_project\\nBuilds project using pnpm build command.\\n```typescript\\ninterface BuildResult {\\n success: boolean;\\n output: string | null;\\n error: string | null;\\n}\\n```\\n\\n## Development\\n\\n```bash\\n# Run in development mode\\npnpm dev\\n\\n# List available tools\\npnpm dev list\\n\\n# Generate types\\npnpm types\\n\\n# Build project\\npnpm build\\n```\\n\\n## Key Features\\n\\n- Type-safe CLI with Zod schemas and TypeScript\\n- File operations (list, remove)\\n- NPM project operations\\n- Built-in logging with tslog\\n- Custom configuration system\\n- OpenAI integration support\\n\\n## Dependencies\\n\\n- tslog: Type-safe logging\\n- yargs: CLI argument parsing\\n- zod: Schema validation\\n- axios: HTTP client\\n- openai: OpenAI API client\\n- @plastichub packages: Core utilities, filesystem operations, and logging\\n\\n## License\\n\\nMIT\"\n },\n {\n \"path\": \"src\\\\zod_types.ts\",\n \"content\": \"export interface IOptions {\\n /** Directory path to list files from */\\n directory: string;\\n /** Glob pattern for filtering files */\\n pattern?: string | undefined;\\n}\\nexport interface IOptions {\\n /** Path of the file to remove */\\n path: string;\\n}\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\nexport const ListFilesSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n});\\n\\nexport const RemoveFileSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n});\\n\"\n },\n {\n \"path\": \"src\\\\tools.ts\",\n \"content\": \"import { tools as fsTools } from './lib/tools/fs';\\nimport { tools as npmTools } from './lib/tools/npm';\\n\\nexport const tools = {\\n fs: fsTools,\\n npm: npmTools\\n};\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport yargs from 'yargs';\\nimport { commands } from './commands';\\nimport { logger } from './';\\n\\nasync function main() {\\n try {\\n const argv = await commands(yargs).argv;\\n } catch (error) {\\n logger.error('Error executing command:', error);\\n process.exit(1);\\n }\\n}\\n\\nmain();\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\npm.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'build_project',\\n description: 'Build project using pnpm build command',\\n parameters: {\\n type: 'object',\\n properties: {},\\n required: []\\n },\\n function: async () => {\\n try {\\n logger.debug(`Tool::BuildProject Building project at ${target}`);\\n const { stdout, stderr } = await execAsync('pnpm build', {\\n cwd: target\\n });\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error : any) {\\n logger.error('Error building project', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { ListFilesSchema, RemoveFileSchema } from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n ListFilesSchema,\\n RemoveFileSchema\\n ], 'src/zod_types.ts');\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\list.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\n\\nexport const list = async () => {\\n // Initialize tools with current directory\\n const fsTools = tools.fs(process.cwd());\\n const npmTools = tools.npm(process.cwd());\\n\\n logger.info('Available Tools:\\\\n');\\n \\n logger.info('Filesystem Tools:');\\n fsTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nNPM Tools:');\\n npmTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\nimport { list } from './list';\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons';\\nimport { logger } from '../';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .command('list', 'List all available tools and their descriptions', {}, list)\\n .option('env_key', {\\n type: 'string',\\n description: 'Environment configuration key'\\n })\\n .middleware([(argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any;\\n if (!config) {\\n logger.warn('No config found!');\\n return;\\n }\\n return config;\\n }])\\n .strict()\\n .help();\\n};\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T12:31:47.258Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = join(target, file.path)\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : Extend command/invoke for an optional output path\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\",\\n \\\"list\\\": \\\"ts-node src/main.ts list\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nA command-line interface and library for LLM (Language Model) tools with filesystem operations support.\\n\\n## Setup\\n\\n1. Clone the repository\\n2. Install dependencies:\\n```bash\\npnpm install\\n```\\n\\n3. Build the project:\\n```bash\\npnpm build\\n```\\n\\n4. Link the CLI (optional):\\n```bash\\npnpm link\\n```\\n\\n## Configuration\\n\\nConfiguration is loaded from multiple sources in this order:\\n1. Command line arguments (--env_key)\\n2. Environment variables (OPENAI_API_KEY)\\n3. Configuration file\\n\\nConfig file example:\\n```json\\n{\\n \\\"openai\\\": {\\n \\\"key\\\": \\\"your-openai-key\\\"\\n }\\n}\\n```\\n\\n## Command Line Usage\\n\\n### List Available Tools\\n```bash\\nllm-tools list\\n```\\nDisplays all available tools and their descriptions.\\n\\n### Generate TypeScript Types\\n```bash\\nllm-tools types\\n```\\nGenerates TypeScript interfaces from Zod schemas in the project.\\n\\n### Invoke Tool Functions\\n```bash\\n# List files in a directory\\nllm-tools invoke --tools=fs --function=list_files --target=./ --params='{\\\"directory\\\":\\\"src\\\",\\\"pattern\\\":\\\"**/*.ts\\\"}'\\n\\n# Remove a file\\nllm-tools invoke --tools=fs --function=remove_file --params='{\\\"path\\\":\\\"temp.txt\\\"}'\\n\\n# Build project\\nllm-tools invoke --tools=npm --function=build_project --target=./my-project\\n```\\n\\n### Global Options\\n```bash\\n--env_key Environment configuration key\\n--help Show help information\\n```\\n\\n## Library Usage\\n\\n### Import Tools\\n\\n```typescript\\nimport { tools } from './tools';\\n\\n// Initialize tools with target directory\\nconst fsTools = tools.fs('./target-directory');\\nconst npmTools = tools.npm('./project-directory');\\n```\\n\\n### Filesystem Tools\\n\\n```typescript\\n// List Files\\nconst listFiles = fsTools.find(t => t.function.name === 'list_files');\\nawait listFiles.function.function({\\n directory: './src',\\n pattern: '**/*.ts'\\n});\\n\\n// Remove File\\nconst removeFile = fsTools.find(t => t.function.name === 'remove_file');\\nawait removeFile.function.function({\\n path: './temp/file.txt'\\n});\\n```\\n\\n### NPM Tools\\n\\n```typescript\\n// Build Project\\nconst buildProject = npmTools.find(t => t.function.name === 'build_project');\\nconst result = await buildProject.function.function();\\n```\\n\\n## Project Structure\\n\\n```\\nsrc/\\n├── index.ts # Logger setup and exports\\n├── main.ts # CLI entry point\\n├── constants.ts # Project constants\\n├── tools.ts # Tools exports\\n├── zod_schemas.ts # Zod schema definitions\\n├── commands/\\n│ ├── index.ts # Command registration\\n│ ├── list.ts # List tools command\\n│ ├── invoke.ts # Invoke tool command\\n│ └── types.ts # Types generation command\\n└── lib/\\n └── tools/\\n ├── fs.ts # Filesystem tools implementation\\n └── npm.ts # NPM tools implementation\\n```\\n\\n## Available Tools\\n\\n### Filesystem Tools\\n\\n#### list_files\\nLists files in a directory with optional pattern matching.\\n```typescript\\ninterface ListFilesParams {\\n directory: string; // Directory to list files from\\n pattern?: string; // Optional glob pattern\\n}\\n```\\n\\n#### remove_file\\nRemoves a file at the specified path.\\n```typescript\\ninterface RemoveFileParams {\\n path: string; // Path to file to remove\\n}\\n```\\n\\n### NPM Tools\\n\\n#### build_project\\nBuilds project using pnpm build command.\\n```typescript\\ninterface BuildResult {\\n success: boolean;\\n output: string | null;\\n error: string | null;\\n}\\n```\\n\\n## Development\\n\\n```bash\\n# Run in development mode\\npnpm dev\\n\\n# List available tools\\npnpm dev list\\n\\n# Generate types\\npnpm types\\n\\n# Build project\\npnpm build\\n\\n# Invoke a tool\\npnpm dev invoke --tools=fs --function=list_files --params='{\\\"directory\\\":\\\"src\\\"}'\\n```\\n\\n## Key Features\\n\\n- Type-safe CLI with Zod schemas and TypeScript\\n- File operations (list, remove)\\n- NPM project operations\\n- Built-in logging with tslog\\n- Custom configuration system\\n- OpenAI integration support\\n- Direct tool invocation via CLI\\n\\n## Dependencies\\n\\n- tslog: Type-safe logging\\n- yargs: CLI argument parsing\\n- zod: Schema validation\\n- axios: HTTP client\\n- openai: OpenAI API client\\n- @plastichub packages: Core utilities, filesystem operations, and logging\\n\\n## License\\n\\nMIT\"\n },\n {\n \"path\": \"src\\\\zod_types.ts\",\n \"content\": \"export interface IOptions {\\n /** Directory path to list files from */\\n directory: string;\\n /** Glob pattern for filtering files */\\n pattern?: string | undefined;\\n}\\nexport interface IOptions {\\n /** Path of the file to remove */\\n path: string;\\n}\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\nexport const ListFilesSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n});\\n\\nexport const RemoveFileSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n});\\n\\nexport const InvokeToolSchema = z.object({\\n tools: z.string().describe('Tool category to use (fs, npm)'),\\n function: z.string().describe('Function name to invoke'),\\n target: z.string().default(process.cwd()).describe('Target directory'),\\n params: z.string().optional().describe('JSON string of parameters')\\n});\\n\"\n },\n {\n \"path\": \"src\\\\tools.ts\",\n \"content\": \"import { tools as fsTools } from './lib/tools/fs';\\nimport { tools as npmTools } from './lib/tools/npm';\\n\\nexport const tools = {\\n fs: fsTools,\\n npm: npmTools\\n};\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport yargs from 'yargs';\\nimport { commands } from './commands';\\nimport { logger } from './';\\n\\nasync function main() {\\n try {\\n const argv = await commands(yargs).argv;\\n } catch (error) {\\n logger.error('Error executing command:', error);\\n process.exit(1);\\n }\\n}\\n\\nmain();\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\npm.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'build_project',\\n description: 'Build project using pnpm build command',\\n parameters: {\\n type: 'object',\\n properties: {},\\n required: []\\n },\\n function: async () => {\\n try {\\n logger.debug(`Tool::BuildProject Building project at ${target}`);\\n const { stdout, stderr } = await execAsync('pnpm build', {\\n cwd: target\\n });\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error : any) {\\n logger.error('Error building project', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { ListFilesSchema, RemoveFileSchema } from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n ListFilesSchema,\\n RemoveFileSchema\\n ], 'src/zod_types.ts');\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\list.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\n\\nexport const list = async () => {\\n // Initialize tools with current directory\\n const fsTools = tools.fs(process.cwd());\\n const npmTools = tools.npm(process.cwd());\\n\\n logger.info('Available Tools:\\\\n');\\n \\n logger.info('Filesystem Tools:');\\n fsTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nNPM Tools:');\\n npmTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\invoke.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { InvokeToolSchema } from '../zod_schemas';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport type { Argv } from 'yargs';\\n\\nconst options = (yargs: Argv) => toYargs(yargs, InvokeToolSchema);\\n\\nexport const invoke = async (argv: any) => {\\n try {\\n const { tools: toolCategory, function: funcName, target, params } = argv;\\n \\n // Get tool category\\n const toolSet = tools[toolCategory];\\n if (!toolSet) {\\n logger.error(`Tool category '${toolCategory}' not found`);\\n return;\\n }\\n\\n // Initialize tools with target directory\\n const toolList = toolSet(target);\\n \\n // Find specific function\\n const tool = toolList.find(t => t.function.name === funcName);\\n if (!tool) {\\n logger.error(`Function '${funcName}' not found in ${toolCategory} tools`);\\n return;\\n }\\n\\n // Parse parameters if provided\\n const parameters = params ? JSON.parse(params) : {};\\n \\n // Execute tool function\\n logger.info(`Invoking ${toolCategory}::${funcName}`);\\n const result = await tool.function.function(parameters);\\n logger.info('Result:', result);\\n \\n return result;\\n } catch (error) {\\n logger.error('Error invoking tool:', error);\\n throw error;\\n }\\n};\\n\\nexport { options as invokeOptions };\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\nimport { list } from './list';\\nimport { invoke, invokeOptions } from './invoke';\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons';\\nimport { logger } from '../';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .command('list', 'List all available tools and their descriptions', {}, list)\\n .command('invoke', 'Invoke a specific tool function', invokeOptions, invoke)\\n .option('env_key', {\\n type: 'string',\\n description: 'Environment configuration key'\\n })\\n .middleware([(argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any;\\n if (!config) {\\n logger.warn('No config found!');\\n return;\\n }\\n return config;\\n }])\\n .strict()\\n .help();\\n};\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T12:33:28.769Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = join(target, file.path)\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : Extend command/list for an optional output path (default:./tools.json). Register it in package.json\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\",\\n \\\"list\\\": \\\"ts-node src/main.ts list\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nA command-line interface and library for LLM (Language Model) tools with filesystem operations support.\\n\\n## Setup\\n\\n1. Clone the repository\\n2. Install dependencies:\\n```bash\\npnpm install\\n```\\n\\n3. Build the project:\\n```bash\\npnpm build\\n```\\n\\n4. Link the CLI (optional):\\n```bash\\npnpm link\\n```\\n\\n## Configuration\\n\\nConfiguration is loaded from multiple sources in this order:\\n1. Command line arguments (--env_key)\\n2. Environment variables (OPENAI_API_KEY)\\n3. Configuration file\\n\\nConfig file example:\\n```json\\n{\\n \\\"openai\\\": {\\n \\\"key\\\": \\\"your-openai-key\\\"\\n }\\n}\\n```\\n\\n## Command Line Usage\\n\\n### List Available Tools\\n```bash\\nllm-tools list\\n```\\nDisplays all available tools and their descriptions.\\n\\n### Generate TypeScript Types\\n```bash\\nllm-tools types\\n```\\nGenerates TypeScript interfaces from Zod schemas in the project.\\n\\n### Invoke Tool Functions\\n```bash\\n# List files in a directory\\nllm-tools invoke --tools=fs --function=list_files --target=./ --params='{\\\"directory\\\":\\\"src\\\",\\\"pattern\\\":\\\"**/*.ts\\\"}'\\n\\n# List files and save output to file\\nllm-tools invoke --tools=fs --function=list_files --target=./ --params='{\\\"directory\\\":\\\"src\\\"}' --output=files.json\\n\\n# Remove a file\\nllm-tools invoke --tools=fs --function=remove_file --params='{\\\"path\\\":\\\"temp.txt\\\"}'\\n\\n# Build project\\nllm-tools invoke --tools=npm --function=build_project --target=./my-project\\n```\\n\\n### Invoke Command Options\\n```bash\\n--tools Tool category to use (fs, npm)\\n--function Function name to invoke\\n--target Target directory (defaults to current directory)\\n--params JSON string of parameters\\n--output Optional path to write the output to\\n```\\n\\n### Global Options\\n```bash\\n--env_key Environment configuration key\\n--help Show help information\\n```\\n\\n## Library Usage\\n\\n### Import Tools\\n\\n```typescript\\nimport { tools } from './tools';\\n\\n// Initialize tools with target directory\\nconst fsTools = tools.fs('./target-directory');\\nconst npmTools = tools.npm('./project-directory');\\n```\\n\\n### Filesystem Tools\\n\\n```typescript\\n// List Files\\nconst listFiles = fsTools.find(t => t.function.name === 'list_files');\\nawait listFiles.function.function({\\n directory: './src',\\n pattern: '**/*.ts'\\n});\\n\\n// Remove File\\nconst removeFile = fsTools.find(t => t.function.name === 'remove_file');\\nawait removeFile.function.function({\\n path: './temp/file.txt'\\n});\\n```\\n\\n### NPM Tools\\n\\n```typescript\\n// Build Project\\nconst buildProject = npmTools.find(t => t.function.name === 'build_project');\\nconst result = await buildProject.function.function();\\n```\\n\\n## Project Structure\\n\\n```\\nsrc/\\n├── index.ts # Logger setup and exports\\n├── main.ts # CLI entry point\\n├── constants.ts # Project constants\\n├── tools.ts # Tools exports\\n├── zod_schemas.ts # Zod schema definitions\\n├── commands/\\n│ ├── index.ts # Command registration\\n│ ├── list.ts # List tools command\\n│ ├── invoke.ts # Invoke tool command\\n│ └── types.ts # Types generation command\\n└── lib/\\n └── tools/\\n ├── fs.ts # Filesystem tools implementation\\n └── npm.ts # NPM tools implementation\\n```\\n\\n## Available Tools\\n\\n### Filesystem Tools\\n\\n#### list_files\\nLists files in a directory with optional pattern matching.\\n```typescript\\ninterface ListFilesParams {\\n directory: string; // Directory to list files from\\n pattern?: string; // Optional glob pattern\\n}\\n```\\n\\n#### remove_file\\nRemoves a file at the specified path.\\n```typescript\\ninterface RemoveFileParams {\\n path: string; // Path to file to remove\\n}\\n```\\n\\n### NPM Tools\\n\\n#### build_project\\nBuilds project using pnpm build command.\\n```typescript\\ninterface BuildResult {\\n success: boolean;\\n output: string | null;\\n error: string | null;\\n}\\n```\\n\\n## Development\\n\\n```bash\\n# Run in development mode\\npnpm dev\\n\\n# List available tools\\npnpm dev list\\n\\n# Generate types\\npnpm types\\n\\n# Build project\\npnpm build\\n\\n# Invoke a tool\\npnpm dev invoke --tools=fs --function=list_files --params='{\\\"directory\\\":\\\"src\\\"}'\\n\\n# Invoke with output to file\\npnpm dev invoke --tools=fs --function=list_files --params='{\\\"directory\\\":\\\"src\\\"}' --output=files.json\\n```\\n\\n## Key Features\\n\\n- Type-safe CLI with Zod schemas and TypeScript\\n- File operations (list, remove)\\n- NPM project operations\\n- Built-in logging with tslog\\n- Custom configuration system\\n- OpenAI integration support\\n- Direct tool invocation via CLI\\n- Output redirection to files\\n\\n## Dependencies\\n\\n- tslog: Type-safe logging\\n- yargs: CLI argument parsing\\n- zod: Schema validation\\n- axios: HTTP client\\n- openai: OpenAI API client\\n- @plastichub packages: Core utilities, filesystem operations, and logging\\n\\n## License\\n\\nMIT\"\n },\n {\n \"path\": \"src\\\\zod_types.ts\",\n \"content\": \"export interface IOptions {\\n /** Directory path to list files from */\\n directory: string;\\n /** Glob pattern for filtering files */\\n pattern?: string | undefined;\\n}\\nexport interface IOptions {\\n /** Path of the file to remove */\\n path: string;\\n}\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\nexport const ListFilesSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n});\\n\\nexport const RemoveFileSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n});\\n\\nexport const InvokeToolSchema = z.object({\\n tools: z.string().describe('Tool category to use (fs, npm)'),\\n function: z.string().describe('Function name to invoke'),\\n target: z.string().default(process.cwd()).describe('Target directory'),\\n params: z.string().optional().describe('JSON string of parameters'),\\n output: z.string().optional().describe('Path to write the output to')\\n});\\n\"\n },\n {\n \"path\": \"src\\\\tools.ts\",\n \"content\": \"import { tools as fsTools } from './lib/tools/fs';\\nimport { tools as npmTools } from './lib/tools/npm';\\n\\nexport const tools = {\\n fs: fsTools,\\n npm: npmTools\\n};\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport yargs from 'yargs';\\nimport { commands } from './commands';\\nimport { logger } from './';\\n\\nasync function main() {\\n try {\\n const argv = await commands(yargs).argv;\\n } catch (error) {\\n logger.error('Error executing command:', error);\\n process.exit(1);\\n }\\n}\\n\\nmain();\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\npm.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'build_project',\\n description: 'Build project using pnpm build command',\\n parameters: {\\n type: 'object',\\n properties: {},\\n required: []\\n },\\n function: async () => {\\n try {\\n logger.debug(`Tool::BuildProject Building project at ${target}`);\\n const { stdout, stderr } = await execAsync('pnpm build', {\\n cwd: target\\n });\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error : any) {\\n logger.error('Error building project', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { ListFilesSchema, RemoveFileSchema } from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n ListFilesSchema,\\n RemoveFileSchema\\n ], 'src/zod_types.ts');\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\list.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\n\\nexport const list = async () => {\\n // Initialize tools with current directory\\n const fsTools = tools.fs(process.cwd());\\n const npmTools = tools.npm(process.cwd());\\n\\n logger.info('Available Tools:\\\\n');\\n \\n logger.info('Filesystem Tools:');\\n fsTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nNPM Tools:');\\n npmTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\invoke.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { InvokeToolSchema } from '../zod_schemas';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport type { Argv } from 'yargs';\\nimport * as path from 'path';\\n\\nconst options = (yargs: Argv) => toYargs(yargs, InvokeToolSchema);\\n\\nexport const invoke = async (argv: any) => {\\n try {\\n const { tools: toolCategory, function: funcName, target, params, output } = argv;\\n \\n // Get tool category\\n const toolSet = tools[toolCategory];\\n if (!toolSet) {\\n logger.error(`Tool category '${toolCategory}' not found`);\\n return;\\n }\\n\\n // Initialize tools with target directory\\n const toolList = toolSet(target);\\n \\n // Find specific function\\n const tool = toolList.find(t => t.function.name === funcName);\\n if (!tool) {\\n logger.error(`Function '${funcName}' not found in ${toolCategory} tools`);\\n return;\\n }\\n\\n // Parse parameters if provided\\n const parameters = params ? JSON.parse(params) : {};\\n \\n // Execute tool function\\n logger.info(`Invoking ${toolCategory}::${funcName}`);\\n const result = await tool.function.function(parameters);\\n \\n // Handle output\\n if (output) {\\n const outputPath = path.isAbsolute(output) ? output : path.join(process.cwd(), output);\\n logger.info(`Writing output to ${outputPath}`);\\n write(outputPath, JSON.stringify(result, null, 2));\\n } else {\\n logger.info('Result:', result);\\n }\\n \\n return result;\\n } catch (error) {\\n logger.error('Error invoking tool:', error);\\n throw error;\\n }\\n};\\n\\nexport { options as invokeOptions };\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\nimport { list } from './list';\\nimport { invoke, invokeOptions } from './invoke';\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons';\\nimport { logger } from '../';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .command('list', 'List all available tools and their descriptions', {}, list)\\n .command('invoke', 'Invoke a specific tool function', invokeOptions, invoke)\\n .option('env_key', {\\n type: 'string',\\n description: 'Environment configuration key'\\n })\\n .middleware([(argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any;\\n if (!config) {\\n logger.warn('No config found!');\\n return;\\n }\\n return config;\\n }])\\n .strict()\\n .help();\\n};\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T12:35:14.794Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n### LLM Tools\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { resolve } from \"@plastichub/osr-commons\"\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any, variables:Record={}): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = path.resolve(resolve(join(target, file.path),false,variables))\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : Apply all instructions as specified in LLMTools (resolving paths with variables with osr-commons::resolve)\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\",\\n \\\"list\\\": \\\"ts-node src/main.ts list\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nA command-line interface and library for LLM (Language Model) tools with filesystem operations support.\\n\\n## Installation\\n\\n```bash\\n# Clone repository\\ngit clone [repository-url]\\ncd llm-tools-cli\\n\\n# Install dependencies\\npnpm install\\n\\n# Build project\\npnpm build\\n\\n# Optional: Link globally\\npnpm link\\n```\\n\\n## Configuration\\n\\nConfiguration is loaded in the following order:\\n1. Command line arguments (--env_key)\\n2. Environment variables (OPENAI_API_KEY)\\n3. Configuration file\\n\\nExample configuration file:\\n```json\\n{\\n \\\"openai\\\": {\\n \\\"key\\\": \\\"your-openai-key\\\"\\n }\\n}\\n```\\n\\n## CLI Commands\\n\\n### List Available Tools\\n```bash\\n# List tools to console\\nllm-tools list\\n\\n# Export tools list to JSON file\\nllm-tools list --output=./tools.json\\n```\\n\\n### Generate TypeScript Types\\n```bash\\nllm-tools types\\n```\\n\\n### Invoke Tool Functions\\n```bash\\n# List files with glob pattern\\nllm-tools invoke --tools=fs --function=list_files --params='{\\\"directory\\\":\\\"src\\\",\\\"pattern\\\":\\\"**/*.ts\\\"}'\\n\\n# Remove file\\nllm-tools invoke --tools=fs --function=remove_file --params='{\\\"path\\\":\\\"temp.txt\\\"}'\\n\\n# Build project\\nllm-tools invoke --tools=npm --function=build_project --target=./my-project\\n```\\n\\n### Command Options\\n\\n#### Global Options\\n- `--env_key`: Environment configuration key\\n- `--help`: Show help information\\n\\n#### List Command\\n- `--output`: Optional JSON file path to save tools list (default: ./tools.json)\\n\\n#### Invoke Command\\n- `--tools`: Tool category (fs, npm)\\n- `--function`: Function name to invoke\\n- `--target`: Target directory (default: current directory)\\n- `--params`: JSON string of parameters\\n- `--output`: Optional output file path\\n\\n## Library Usage\\n\\n### Tools Setup\\n```typescript\\nimport { tools } from './tools';\\n\\n// Initialize with target directory\\nconst fsTools = tools.fs('./target-dir');\\nconst npmTools = tools.npm('./project-dir');\\n```\\n\\n### Filesystem Operations\\n```typescript\\n// List Files\\nconst listFiles = fsTools.find(t => t.function.name === 'list_files');\\nconst files = await listFiles.function.function({\\n directory: './src',\\n pattern: '**/*.ts'\\n});\\n\\n// Remove File\\nconst removeFile = fsTools.find(t => t.function.name === 'remove_file');\\nawait removeFile.function.function({\\n path: './temp.txt'\\n});\\n```\\n\\n### NPM Operations\\n```typescript\\n// Build Project\\nconst buildProject = npmTools.find(t => t.function.name === 'build_project');\\nconst result = await buildProject.function.function();\\n```\\n\\n## Development Scripts\\n\\n```bash\\n# Development mode\\npnpm dev\\n\\n# Generate TypeScript types\\npnpm types\\n\\n# List tools\\npnpm list\\n\\n# Build project\\npnpm build\\n```\\n\\n## Project Structure\\n\\n```\\nsrc/\\n├── index.ts # Logger setup\\n├── main.ts # CLI entry point\\n├── constants.ts # Project constants\\n├── tools.ts # Tools exports\\n├── zod_schemas.ts # Zod schemas\\n├── commands/\\n│ ├── index.ts # Command registration\\n│ ├── list.ts # List tools command\\n│ ├── invoke.ts # Invoke tool command\\n│ └── types.ts # Types generation\\n└── lib/\\n └── tools/\\n ├── fs.ts # Filesystem tools\\n └── npm.ts # NPM tools\\n```\\n\\n## Available Tools\\n\\n### Filesystem Tools\\n\\n#### list_files\\n```typescript\\ninterface ListFilesParams {\\n directory: string; // Directory path\\n pattern?: string; // Optional glob pattern\\n}\\n```\\n\\n#### remove_file\\n```typescript\\ninterface RemoveFileParams {\\n path: string; // File path to remove\\n}\\n```\\n\\n### NPM Tools\\n\\n#### build_project\\n```typescript\\ninterface BuildResult {\\n success: boolean;\\n output: string | null;\\n error: string | null;\\n}\\n```\\n\\n## Dependencies\\n\\n- tslog: Logging\\n- yargs: CLI parsing\\n- zod: Schema validation\\n- axios: HTTP client\\n- openai: OpenAI API\\n- @plastichub packages: Core utilities\\n\\n## License\\n\\nMIT\"\n },\n {\n \"path\": \"src\\\\zod_types.ts\",\n \"content\": \"export interface IOptions {\\n /** Directory path to list files from */\\n directory: string;\\n /** Glob pattern for filtering files */\\n pattern?: string | undefined;\\n}\\nexport interface IOptions {\\n /** Path of the file to remove */\\n path: string;\\n}\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\nexport const ListFilesSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n});\\n\\nexport const RemoveFileSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n});\\n\\nexport const InvokeToolSchema = z.object({\\n tools: z.string().describe('Tool category to use (fs, npm)'),\\n function: z.string().describe('Function name to invoke'),\\n target: z.string().default(process.cwd()).describe('Target directory'),\\n params: z.string().optional().describe('JSON string of parameters'),\\n output: z.string().optional().describe('Path to write the output to')\\n});\\n\\nexport const ListCommandSchema = z.object({\\n output: z.string().default('./llm-tools.json').describe('Output file path for tools list')\\n});\"\n },\n {\n \"path\": \"src\\\\tools.ts\",\n \"content\": \"import { tools as fsTools } from './lib/tools/fs';\\nimport { tools as npmTools } from './lib/tools/npm';\\n\\nexport const tools = {\\n fs: fsTools,\\n npm: npmTools\\n};\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport yargs from 'yargs';\\nimport { commands } from './commands';\\nimport { logger } from './';\\n\\nasync function main() {\\n try {\\n const argv = await commands(yargs).argv;\\n } catch (error) {\\n logger.error('Error executing command:', error);\\n process.exit(1);\\n }\\n}\\n\\nmain();\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\npm.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'build_project',\\n description: 'Build project using pnpm build command',\\n parameters: {\\n type: 'object',\\n properties: {},\\n required: []\\n },\\n function: async () => {\\n try {\\n logger.debug(`Tool::BuildProject Building project at ${target}`);\\n const { stdout, stderr } = await execAsync('pnpm build', {\\n cwd: target\\n });\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error : any) {\\n logger.error('Error building project', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { ListFilesSchema, RemoveFileSchema } from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n ListFilesSchema,\\n RemoveFileSchema\\n ], 'src/zod_types.ts');\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\list.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { ListCommandSchema } from '../zod_schemas';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport type { Argv } from 'yargs';\\n\\nexport const options = (yargs: Argv) => toYargs(yargs, ListCommandSchema);\\n\\nexport const list = async (argv: any) => {\\n // Initialize tools with current directory\\n const fsTools = tools.fs(process.cwd());\\n const npmTools = tools.npm(process.cwd());\\n\\n const toolsList = {\\n fs: fsTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'fs'\\n })),\\n npm: npmTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'npm'\\n }))\\n };\\n\\n logger.info('Available Tools:\\\\n');\\n \\n logger.info('Filesystem Tools:');\\n fsTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nNPM Tools:');\\n npmTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n if (argv.output) {\\n logger.info(`\\\\nWriting tools list to ${argv.output}`);\\n write(argv.output, JSON.stringify(toolsList, null, 2));\\n }\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\invoke.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { InvokeToolSchema } from '../zod_schemas';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport type { Argv } from 'yargs';\\nimport * as path from 'path';\\n\\nconst options = (yargs: Argv) => toYargs(yargs, InvokeToolSchema);\\n\\nexport const invoke = async (argv: any) => {\\n try {\\n const { tools: toolCategory, function: funcName, target, params, output } = argv;\\n \\n // Get tool category\\n const toolSet = tools[toolCategory];\\n if (!toolSet) {\\n logger.error(`Tool category '${toolCategory}' not found`);\\n return;\\n }\\n\\n // Initialize tools with target directory\\n const toolList = toolSet(target);\\n \\n // Find specific function\\n const tool = toolList.find(t => t.function.name === funcName);\\n if (!tool) {\\n logger.error(`Function '${funcName}' not found in ${toolCategory} tools`);\\n return;\\n }\\n\\n // Parse parameters if provided\\n const parameters = params ? JSON.parse(params) : {};\\n \\n // Execute tool function\\n logger.info(`Invoking ${toolCategory}::${funcName}`);\\n const result = await tool.function.function(parameters);\\n \\n // Handle output\\n if (output) {\\n const outputPath = path.isAbsolute(output) ? output : path.join(process.cwd(), output);\\n logger.info(`Writing output to ${outputPath}`);\\n write(outputPath, JSON.stringify(result, null, 2));\\n } else {\\n logger.info('Result:', result);\\n }\\n \\n return result;\\n } catch (error) {\\n logger.error('Error invoking tool:', error);\\n throw error;\\n }\\n};\\n\\nexport { options as invokeOptions };\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\nimport { list, options as listOptions } from './list';\\nimport { invoke, invokeOptions } from './invoke';\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons';\\nimport { logger } from '../';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .command('list', 'List all available tools and their descriptions', listOptions, list)\\n .command('invoke', 'Invoke a specific tool function', invokeOptions, invoke)\\n .option('env_key', {\\n type: 'string',\\n description: 'Environment configuration key'\\n })\\n .middleware([(argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any;\\n if (!config) {\\n logger.warn('No config found!');\\n return;\\n }\\n return config;\\n }])\\n .strict()\\n .help();\\n};\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T12:44:43.228Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n### LLM Tools\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { resolve } from \"@plastichub/osr-commons\"\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any, variables:Record={}): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = path.resolve(resolve(join(target, file.path),false,variables))\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : Update documentation, for all commands and tools\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\",\\n \\\"list\\\": \\\"ts-node src/main.ts list\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nA command-line interface and library for LLM (Language Model) tools with filesystem operations support.\\n\\n## Features\\n\\n- Filesystem operations (list files, remove files)\\n- NPM project operations (build)\\n- TypeScript interface generation from Zod schemas\\n- Configuration management with environment support\\n- Structured logging with tslog\\n\\n## Installation\\n\\n```bash\\n# Clone repository\\ngit clone [repository-url]\\ncd llm-tools-cli\\n\\n# Install dependencies\\npnpm install\\n\\n# Build project\\npnpm build\\n\\n# Optional: Link globally\\npnpm link\\n```\\n\\n## Configuration\\n\\nConfiguration is loaded using @plastichub/osr-commons in the following order:\\n\\n1. Command line arguments (--env_key)\\n2. Environment variables\\n3. Configuration file\\n\\nExample configuration:\\n```json\\n{\\n \\\"openai\\\": {\\n \\\"key\\\": \\\"your-openai-key\\\"\\n }\\n}\\n```\\n\\n## CLI Usage\\n\\n### Generate TypeScript Types\\n```bash\\nllm-tools types\\n```\\n\\n### List Available Tools\\n```bash\\n# List all tools\\nllm-tools list\\n\\n# Export tools list to file\\nllm-tools list --output=tools.json\\n```\\n\\n### Invoke Tools\\n```bash\\n# List files in directory\\nllm-tools invoke --tools=fs --function=list_files --params='{\\\"directory\\\":\\\"src\\\",\\\"pattern\\\":\\\"**/*.ts\\\"}'\\n\\n# Remove a file\\nllm-tools invoke --tools=fs --function=remove_file --params='{\\\"path\\\":\\\"temp.txt\\\"}'\\n\\n# Build project\\nllm-tools invoke --tools=npm --function=build_project --target=./my-project\\n```\\n\\n## Library Usage\\n\\n### Initialize Logger\\n```typescript\\nimport { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\n\\nexport const logger: Logger = createLogger('your-package-name');\\n```\\n\\n### Using Filesystem Tools\\n```typescript\\nimport { tools } from './tools';\\n\\n// Initialize with target directory\\nconst fsTools = tools.fs('./target-dir');\\n\\n// List files\\nconst files = await fsTools.find(t => t.function.name === 'list_files')\\n .function.function({\\n directory: 'src',\\n pattern: '**/*.ts'\\n });\\n\\n// Remove file\\nawait fsTools.find(t => t.function.name === 'remove_file')\\n .function.function({\\n path: 'temp.txt'\\n });\\n```\\n\\n### Using NPM Tools\\n```typescript\\nimport { tools } from './tools';\\n\\n// Initialize with project directory\\nconst npmTools = tools.npm('./project-dir');\\n\\n// Build project\\nconst result = await npmTools.find(t => t.function.name === 'build_project')\\n .function.function();\\n```\\n\\n### Creating Zod Schemas\\n```typescript\\nimport { z } from 'zod';\\n\\nexport const MySchema = z.object({\\n field: z.string().describe('Field description')\\n});\\n```\\n\\n### Converting Zod Schema to Yargs\\n```typescript\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport { MySchema } from '../schemas';\\n\\nexport const options = (yargs: Argv) => toYargs(yargs, MySchema);\\n```\\n\\n## Project Structure\\n\\n```\\nsrc/\\n├── index.ts # Logger setup\\n├── main.ts # CLI entry point\\n├── constants.ts # Project constants\\n├── tools.ts # Tools exports\\n├── zod_schemas.ts # Zod schemas\\n├── zod_types.ts # Generated TypeScript interfaces\\n├── commands/\\n│ ├── index.ts # Command registration\\n│ ├── list.ts # List tools command\\n│ ├── invoke.ts # Invoke tool command\\n│ └── types.ts # Types generation\\n└── lib/\\n └── tools/\\n ├── fs.ts # Filesystem tools\\n └── npm.ts # NPM tools\\n```\\n\\n## Development\\n\\n```bash\\n# Run in development mode\\npnpm dev\\n\\n# Build project\\npnpm build\\n\\n# Generate TypeScript interfaces\\npnpm types\\n\\n# List available tools\\npnpm list\\n```\\n\\n## Dependencies\\n\\nCore dependencies:\\n- tslog: Structured logging\\n- yargs: CLI argument parsing\\n- zod: Schema validation\\n- axios: HTTP client\\n- openai: OpenAI API client\\n\\nPlastichub packages:\\n- @plastichub/core: Core utilities\\n- @plastichub/fs: Filesystem operations\\n- @plastichub/osr-commons: Common utilities\\n- @plastichub/osr-log: Logging setup\\n\\n## License\\n\\nMIT\\n\"\n },\n {\n \"path\": \"src\\\\zod_types.ts\",\n \"content\": \"export interface IOptions {\\n /** Directory path to list files from */\\n directory: string;\\n /** Glob pattern for filtering files */\\n pattern?: string | undefined;\\n}\\nexport interface IOptions {\\n /** Path of the file to remove */\\n path: string;\\n}\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\nexport const ListFilesSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n});\\n\\nexport const RemoveFileSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n});\\n\\nexport const InvokeToolSchema = z.object({\\n tools: z.string().describe('Tool category to use (fs, npm)'),\\n function: z.string().describe('Function name to invoke'),\\n target: z.string().default(process.cwd()).describe('Target directory'),\\n params: z.string().optional().describe('JSON string of parameters'),\\n output: z.string().optional().describe('Path to write the output to')\\n});\\n\\nexport const ListCommandSchema = z.object({\\n output: z.string().default('./llm-tools.json').describe('Output file path for tools list')\\n});\"\n },\n {\n \"path\": \"src\\\\tools.ts\",\n \"content\": \"import { tools as fsTools } from './lib/tools/fs';\\nimport { tools as npmTools } from './lib/tools/npm';\\n\\nexport const tools = {\\n fs: fsTools,\\n npm: npmTools\\n};\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport yargs from 'yargs';\\nimport { commands } from './commands';\\nimport { logger } from './';\\n\\nasync function main() {\\n try {\\n const argv = await commands(yargs).argv;\\n } catch (error) {\\n logger.error('Error executing command:', error);\\n process.exit(1);\\n }\\n}\\n\\nmain();\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\npm.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'build_project',\\n description: 'Build project using pnpm build command',\\n parameters: {\\n type: 'object',\\n properties: {},\\n required: []\\n },\\n function: async () => {\\n try {\\n logger.debug(`Tool::BuildProject Building project at ${target}`);\\n const { stdout, stderr } = await execAsync('pnpm build', {\\n cwd: target\\n });\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error : any) {\\n logger.error('Error building project', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { ListFilesSchema, RemoveFileSchema } from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n ListFilesSchema,\\n RemoveFileSchema\\n ], 'src/zod_types.ts');\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\list.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { ListCommandSchema } from '../zod_schemas';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport type { Argv } from 'yargs';\\n\\nexport const options = (yargs: Argv) => toYargs(yargs, ListCommandSchema);\\n\\nexport const list = async (argv: any) => {\\n // Initialize tools with current directory\\n const fsTools = tools.fs(process.cwd());\\n const npmTools = tools.npm(process.cwd());\\n\\n const toolsList = {\\n fs: fsTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'fs'\\n })),\\n npm: npmTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'npm'\\n }))\\n };\\n\\n logger.info('Available Tools:\\\\n');\\n \\n logger.info('Filesystem Tools:');\\n fsTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nNPM Tools:');\\n npmTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n if (argv.output) {\\n logger.info(`\\\\nWriting tools list to ${argv.output}`);\\n write(argv.output, JSON.stringify(toolsList, null, 2));\\n }\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\invoke.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { InvokeToolSchema } from '../zod_schemas';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport type { Argv } from 'yargs';\\nimport * as path from 'path';\\n\\nconst options = (yargs: Argv) => toYargs(yargs, InvokeToolSchema);\\n\\nexport const invoke = async (argv: any) => {\\n try {\\n const { tools: toolCategory, function: funcName, target, params, output } = argv;\\n \\n // Get tool category\\n const toolSet = tools[toolCategory];\\n if (!toolSet) {\\n logger.error(`Tool category '${toolCategory}' not found`);\\n return;\\n }\\n\\n // Initialize tools with target directory\\n const toolList = toolSet(target);\\n \\n // Find specific function\\n const tool = toolList.find(t => t.function.name === funcName);\\n if (!tool) {\\n logger.error(`Function '${funcName}' not found in ${toolCategory} tools`);\\n return;\\n }\\n\\n // Parse parameters if provided\\n const parameters = params ? JSON.parse(params) : {};\\n \\n // Execute tool function\\n logger.info(`Invoking ${toolCategory}::${funcName}`);\\n const result = await tool.function.function(parameters);\\n \\n // Handle output\\n if (output) {\\n const outputPath = path.isAbsolute(output) ? output : path.join(process.cwd(), output);\\n logger.info(`Writing output to ${outputPath}`);\\n write(outputPath, JSON.stringify(result, null, 2));\\n } else {\\n logger.info('Result:', result);\\n }\\n \\n return result;\\n } catch (error) {\\n logger.error('Error invoking tool:', error);\\n throw error;\\n }\\n};\\n\\nexport { options as invokeOptions };\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\nimport { list, options as listOptions } from './list';\\nimport { invoke, invokeOptions } from './invoke';\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons';\\nimport { logger } from '../';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .command('list', 'List all available tools and their descriptions', listOptions, list)\\n .command('invoke', 'Invoke a specific tool function', invokeOptions, invoke)\\n .option('env_key', {\\n type: 'string',\\n description: 'Environment configuration key'\\n })\\n .middleware([(argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any;\\n if (!config) {\\n logger.warn('No config found!');\\n return;\\n }\\n return config;\\n }])\\n .strict()\\n .help();\\n};\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T12:56:06.662Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n### LLM Tools\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { resolve } from \"@plastichub/osr-commons\"\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any, variables:Record={}): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = path.resolve(resolve(join(target, file.path),false,variables))\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : 1. Give all Zod schemas names. 2. Update documentation, for all commands and tools\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\",\\n \\\"list\\\": \\\"ts-node src/main.ts list\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nA command-line interface and library for Language Model tools with filesystem operations support.\\n\\n## Installation\\n\\n```bash\\n# Install dependencies\\npnpm install\\n\\n# Build project\\npnpm build\\n\\n# Generate TypeScript types\\npnpm types\\n```\\n\\n## CLI Commands\\n\\n### Generate TypeScript Types\\nGenerates TypeScript interfaces from Zod schemas.\\n\\n```bash\\npnpm types\\n# or\\nllm-tools types\\n```\\n\\n### List Available Tools\\nDisplays all available tools and their descriptions.\\n\\n```bash\\npnpm list\\n# or\\nllm-tools list [options]\\n\\nOptions:\\n --output Output file path for tools list [default: \\\"./llm-tools.json\\\"]\\n```\\n\\n### Invoke Tools\\nInvokes a specific tool function.\\n\\n```bash\\nllm-tools invoke [options]\\n\\nOptions:\\n --tools Tool category to use (fs, npm)\\n --function Function name to invoke\\n --target Target directory [default: current working directory]\\n --params JSON string of parameters\\n --output Path to write the output to\\n```\\n\\nExample:\\n```bash\\n# List files in directory\\nllm-tools invoke --tools=fs --function=list_files --params='{\\\"directory\\\":\\\"src\\\",\\\"pattern\\\":\\\"**/*.ts\\\"}'\\n\\n# Build project\\nllm-tools invoke --tools=npm --function=build_project --target=./my-project\\n```\\n\\n## Configuration\\n\\nConfiguration is loaded using the following priority:\\n\\n1. Command line arguments (--env_key)\\n2. Environment variables\\n3. Configuration file\\n\\n```typescript\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\\n\\n// In your command:\\nconst config = CONFIG_DEFAULT(args.env_key) as any\\nif (!config) {\\n logger.warn('No config found!')\\n return\\n}\\n```\\n\\n## Library Usage\\n\\n### Logger Setup\\n```typescript\\nimport { Logger } from 'tslog'\\nimport { createLogger } from '@plastichub/osr-log'\\n\\nexport const logger: Logger = createLogger('your-package-name')\\n```\\n\\n### Filesystem Operations\\n```typescript\\nimport { sync as rm } from '@plastichub/fs/remove'\\nimport { sync as dir } from '@plastichub/fs/dir'\\nimport { sync as write } from '@plastichub/fs/write'\\nimport { sync as read } from '@plastichub/fs/read'\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob'\\n```\\n\\n### Tools Implementation\\n\\n```typescript\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\\n\\nexport const tools = (target: string): Array => {\\n return [{\\n type: 'function',\\n function: {\\n name: 'tool_name',\\n description: 'Tool description',\\n parameters: {\\n type: 'object',\\n properties: {\\n // parameters\\n },\\n required: []\\n },\\n function: async (params) => {\\n // implementation\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction]\\n}\\n```\\n\\n### Zod Schemas\\n\\n```typescript\\nimport { z } from 'zod'\\n\\nexport const MySchema = z.object({\\n field: z.string().describe('Field description')\\n})\\n\\n// Convert to Yargs\\nimport { toYargs } from '@plastichub/osr-commons'\\nconst options = (yargs: Argv) => toYargs(yargs, MySchema)\\n```\\n\\n### Command Registration\\n\\n```typescript\\nimport type { Argv } from 'yargs'\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('command', 'description', options, handler)\\n .strict()\\n .help()\\n}\\n```\\n\\n## Project Structure\\n\\n```\\nsrc/\\n├── index.ts # Logger setup\\n├── main.ts # CLI entry point\\n├── constants.ts # Project constants\\n├── tools.ts # Tools exports\\n├── zod_schemas.ts # Zod schemas\\n├── zod_types.ts # Generated TypeScript interfaces\\n├── commands/\\n│ ├── index.ts # Command registration\\n│ ├── list.ts # List tools command\\n│ ├── invoke.ts # Invoke tool command\\n│ └── types.ts # Types generation\\n└── lib/\\n └── tools/\\n ├── fs.ts # Filesystem tools\\n └── npm.ts # NPM tools\\n```\\n\\n## Dependencies\\n\\n### Core Dependencies\\n- tslog: Structured logging\\n- yargs: CLI argument parsing\\n- zod: Schema validation\\n- axios: HTTP client\\n- openai: OpenAI API client\\n\\n### Plastichub Packages\\n- @plastichub/core: Core utilities\\n- @plastichub/fs: Filesystem operations\\n- @plastichub/osr-commons: Common utilities\\n- @plastichub/osr-log: Logging setup\"\n },\n {\n \"path\": \"src\\\\zod_types.ts\",\n \"content\": \"export interface IOptions {\\n /** Directory path to list files from */\\n directory: string;\\n /** Glob pattern for filtering files */\\n pattern?: string | undefined;\\n}\\nexport interface IOptions {\\n /** Path of the file to remove */\\n path: string;\\n}\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\nexport const ListFilesSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n});\\n\\nexport const RemoveFileSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n});\\n\\nexport const InvokeToolSchema = z.object({\\n tools: z.string().describe('Tool category to use (fs, npm)'),\\n function: z.string().describe('Function name to invoke'),\\n target: z.string().default(process.cwd()).describe('Target directory'),\\n params: z.string().optional().describe('JSON string of parameters'),\\n output: z.string().optional().describe('Path to write the output to')\\n});\\n\\nexport const ListCommandSchema = z.object({\\n output: z.string().default('./llm-tools.json').describe('Output file path for tools list')\\n});\"\n },\n {\n \"path\": \"src\\\\tools.ts\",\n \"content\": \"import { tools as fsTools } from './lib/tools/fs';\\nimport { tools as npmTools } from './lib/tools/npm';\\n\\nexport const tools = {\\n fs: fsTools,\\n npm: npmTools\\n};\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport yargs from 'yargs';\\nimport { commands } from './commands';\\nimport { logger } from './';\\n\\nasync function main() {\\n try {\\n const argv = await commands(yargs).argv;\\n } catch (error) {\\n logger.error('Error executing command:', error);\\n process.exit(1);\\n }\\n}\\n\\nmain();\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\npm.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'build_project',\\n description: 'Build project using pnpm build command',\\n parameters: {\\n type: 'object',\\n properties: {},\\n required: []\\n },\\n function: async () => {\\n try {\\n logger.debug(`Tool::BuildProject Building project at ${target}`);\\n const { stdout, stderr } = await execAsync('pnpm build', {\\n cwd: target\\n });\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error : any) {\\n logger.error('Error building project', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { ListFilesSchema, RemoveFileSchema } from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n ListFilesSchema,\\n RemoveFileSchema\\n ], 'src/zod_types.ts');\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\list.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { ListCommandSchema } from '../zod_schemas';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport type { Argv } from 'yargs';\\n\\nexport const options = (yargs: Argv) => toYargs(yargs, ListCommandSchema);\\n\\nexport const list = async (argv: any) => {\\n // Initialize tools with current directory\\n const fsTools = tools.fs(process.cwd());\\n const npmTools = tools.npm(process.cwd());\\n\\n const toolsList = {\\n fs: fsTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'fs'\\n })),\\n npm: npmTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'npm'\\n }))\\n };\\n\\n logger.info('Available Tools:\\\\n');\\n \\n logger.info('Filesystem Tools:');\\n fsTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nNPM Tools:');\\n npmTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n if (argv.output) {\\n logger.info(`\\\\nWriting tools list to ${argv.output}`);\\n write(argv.output, JSON.stringify(toolsList, null, 2));\\n }\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\invoke.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { InvokeToolSchema } from '../zod_schemas';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport type { Argv } from 'yargs';\\nimport * as path from 'path';\\n\\nconst options = (yargs: Argv) => toYargs(yargs, InvokeToolSchema);\\n\\nexport const invoke = async (argv: any) => {\\n try {\\n const { tools: toolCategory, function: funcName, target, params, output } = argv;\\n \\n // Get tool category\\n const toolSet = tools[toolCategory];\\n if (!toolSet) {\\n logger.error(`Tool category '${toolCategory}' not found`);\\n return;\\n }\\n\\n // Initialize tools with target directory\\n const toolList = toolSet(target);\\n \\n // Find specific function\\n const tool = toolList.find(t => t.function.name === funcName);\\n if (!tool) {\\n logger.error(`Function '${funcName}' not found in ${toolCategory} tools`);\\n return;\\n }\\n\\n // Parse parameters if provided\\n const parameters = params ? JSON.parse(params) : {};\\n \\n // Execute tool function\\n logger.info(`Invoking ${toolCategory}::${funcName}`);\\n const result = await tool.function.function(parameters);\\n \\n // Handle output\\n if (output) {\\n const outputPath = path.isAbsolute(output) ? output : path.join(process.cwd(), output);\\n logger.info(`Writing output to ${outputPath}`);\\n write(outputPath, JSON.stringify(result, null, 2));\\n } else {\\n logger.info('Result:', result);\\n }\\n \\n return result;\\n } catch (error) {\\n logger.error('Error invoking tool:', error);\\n throw error;\\n }\\n};\\n\\nexport { options as invokeOptions };\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\nimport { list, options as listOptions } from './list';\\nimport { invoke, invokeOptions } from './invoke';\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons';\\nimport { logger } from '../';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .command('list', 'List all available tools and their descriptions', listOptions, list)\\n .command('invoke', 'Invoke a specific tool function', invokeOptions, invoke)\\n .option('env_key', {\\n type: 'string',\\n description: 'Environment configuration key'\\n })\\n .middleware([(argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any;\\n if (!config) {\\n logger.warn('No config found!');\\n return;\\n }\\n return config;\\n }])\\n .strict()\\n .help();\\n};\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T12:59:49.088Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n### LLM Tools\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { resolve } from \"@plastichub/osr-commons\"\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any, variables:Record={}): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = path.resolve(resolve(join(target, file.path),false,variables))\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : 1. Add missing Zod schemas\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\",\\n \\\"list\\\": \\\"ts-node src/main.ts list\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nA command-line interface and library for Language Model tools with filesystem operations support.\\n\\n## Setup\\n\\n### Prerequisites\\n\\n- Node.js >= 16\\n- pnpm (recommended) or npm\\n\\n### Installation\\n\\n```bash\\n# Clone repository\\ngit clone [repository-url]\\ncd llm-tools-cli\\n\\n# Install dependencies\\npnpm install\\n\\n# Build project\\npnpm build\\n\\n# Generate TypeScript types\\npnpm types\\n```\\n\\n### Configuration\\n\\nCreate a configuration file in your project root or use environment variables:\\n\\n```json\\n{\\n \\\"openai\\\": {\\n \\\"key\\\": \\\"your-api-key\\\"\\n }\\n}\\n```\\n\\nOr use environment variables:\\n```bash\\nexport OPENAI_API_KEY=your-api-key\\n```\\n\\n## CLI Commands\\n\\n### Generate TypeScript Types\\n\\nGenerates TypeScript interfaces from all Zod schemas in the project.\\n\\n```bash\\npnpm types\\n# or\\nllm-tools types\\n```\\n\\n### List Available Tools\\n\\nDisplays all available tools and their descriptions.\\n\\n```bash\\npnpm list\\n# or\\nllm-tools list [options]\\n\\nOptions:\\n --output Output file path for tools list [default: \\\"./llm-tools.json\\\"]\\n```\\n\\n### Invoke Tools\\n\\nExecutes a specific tool function with given parameters.\\n\\n```bash\\nllm-tools invoke [options]\\n\\nOptions:\\n --tools Tool category (fs, npm)\\n --function Function name to invoke\\n --target Target directory [default: current directory]\\n --params JSON string of parameters\\n --output Output file path for results\\n --env_key Environment configuration key\\n```\\n\\nExamples:\\n```bash\\n# List files in directory\\nllm-tools invoke --tools=fs --function=list_files \\\\\\n --params='{\\\"directory\\\":\\\"src\\\",\\\"pattern\\\":\\\"**/*.ts\\\"}'\\n\\n# Build project\\nllm-tools invoke --tools=npm --function=build_project \\\\\\n --target=./my-project\\n```\\n\\n## Library Usage\\n\\n### Filesystem Operations\\n\\n```typescript\\nimport { sync as rm } from '@plastichub/fs/remove'\\nimport { sync as dir } from '@plastichub/fs/dir'\\nimport { sync as write } from '@plastichub/fs/write'\\nimport { sync as read } from '@plastichub/fs/read'\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob'\\n\\n// Examples\\ndir('path/to/create') // Create directory\\nwrite('file.txt', 'content') // Write file\\nconst content = read('file.txt') // Read file\\nrm('path/to/remove') // Remove file/directory\\nconst files = glob('src', ['**/*.ts']) // Find files\\n```\\n\\n### Logging\\n\\n```typescript\\nimport { Logger } from 'tslog'\\nimport { createLogger } from '@plastichub/osr-log'\\n\\nexport const logger: Logger = createLogger('your-package-name')\\n\\n// Usage\\nlogger.info('Info message')\\nlogger.warn('Warning message')\\nlogger.error('Error message')\\nlogger.debug('Debug message')\\n```\\n\\n### Configuration Access\\n\\n```typescript\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\\n\\nconst config = CONFIG_DEFAULT('env_key')\\nif (!config) {\\n logger.warn('No config found!')\\n return\\n}\\n\\n// Access OpenAI key\\nconst apiKey = config.openai?.key || process.env.OPENAI_API_KEY\\n```\\n\\n### Zod Schemas & Yargs Integration\\n\\n```typescript\\nimport { z } from 'zod'\\nimport { toYargs } from '@plastichub/osr-commons'\\n\\n// Define schema\\nconst MySchema = z.object({\\n field: z.string().describe('Field description')\\n})\\n\\n// Convert to Yargs options\\nconst options = (yargs: Argv) => toYargs(yargs, MySchema)\\n```\\n\\n### Available Tools\\n\\n#### Filesystem Tools\\n- `list_files`: List files in directory with optional glob pattern\\n- `remove_file`: Remove file at specified path\\n\\n#### NPM Tools\\n- `build_project`: Build project using pnpm build command\\n\\n## Project Structure\\n\\n```\\nsrc/\\n├── index.ts # Logger setup\\n├── main.ts # CLI entry point\\n├── constants.ts # Project constants\\n├── tools.ts # Tools registry\\n├── zod_schemas.ts # Zod schemas\\n├── zod_types.ts # Generated TypeScript interfaces\\n├── commands/\\n│ ├── index.ts # Command registration\\n│ ├── list.ts # List tools command\\n│ ├── invoke.ts # Invoke tool command\\n│ └── types.ts # Types generation\\n└── lib/\\n └── tools/\\n ├── fs.ts # Filesystem tools\\n └── npm.ts # NPM tools\\n```\\n\\n## Development\\n\\n### Scripts\\n\\n```bash\\npnpm build # Build TypeScript\\npnpm start # Run built version\\npnpm dev # Run with ts-node\\npnpm types # Generate TypeScript interfaces\\npnpm list # List available tools\\n```\\n\\n### Adding New Tools\\n\\n1. Create tool implementation in `src/lib/tools/`\\n2. Register tool in `src/tools.ts`\\n3. Add Zod schema in `src/zod_schemas.ts`\\n4. Update types using `pnpm types`\\n\\n## Dependencies\\n\\n### Core\\n- tslog: Structured logging\\n- yargs: CLI argument parsing\\n- zod: Schema validation\\n- axios: HTTP client\\n- openai: OpenAI API client\\n\\n### Plastichub Packages\\n- @plastichub/core: Core utilities\\n- @plastichub/fs: Filesystem operations\\n- @plastichub/osr-commons: Common utilities\\n- @plastichub/osr-log: Logging setup\"\n },\n {\n \"path\": \"src\\\\zod_types.ts\",\n \"content\": \"export interface IOptions {\\n /** Directory path to list files from */\\n directory: string;\\n /** Glob pattern for filtering files */\\n pattern?: string | undefined;\\n}\\nexport interface IOptions {\\n /** Path of the file to remove */\\n path: string;\\n}\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\n/** Schema for listing files in a directory */\\nexport const FileListingOptionsSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n});\\n\\n/** Schema for file removal operations */\\nexport const FileRemovalOptionsSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n});\\n\\n/** Schema for tool invocation parameters */\\nexport const ToolInvocationOptionsSchema = z.object({\\n tools: z.string().describe('Tool category to use (fs, npm)'),\\n function: z.string().describe('Function name to invoke'),\\n target: z.string().default(process.cwd()).describe('Target directory'),\\n params: z.string().optional().describe('JSON string of parameters'),\\n output: z.string().optional().describe('Path to write the output to')\\n});\\n\\n/** Schema for list command options */\\nexport const ToolListingOptionsSchema = z.object({\\n output: z.string().default('./llm-tools.json').describe('Output file path for tools list')\\n});\"\n },\n {\n \"path\": \"src\\\\tools.ts\",\n \"content\": \"import { tools as fsTools } from './lib/tools/fs';\\nimport { tools as npmTools } from './lib/tools/npm';\\n\\nexport const tools = {\\n fs: fsTools,\\n npm: npmTools\\n};\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport yargs from 'yargs';\\nimport { commands } from './commands';\\nimport { logger } from './';\\n\\nasync function main() {\\n try {\\n const argv = await commands(yargs).argv;\\n } catch (error) {\\n logger.error('Error executing command:', error);\\n process.exit(1);\\n }\\n}\\n\\nmain();\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\npm.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'build_project',\\n description: 'Build project using pnpm build command',\\n parameters: {\\n type: 'object',\\n properties: {},\\n required: []\\n },\\n function: async () => {\\n try {\\n logger.debug(`Tool::BuildProject Building project at ${target}`);\\n const { stdout, stderr } = await execAsync('pnpm build', {\\n cwd: target\\n });\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error : any) {\\n logger.error('Error building project', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { \\n FileListingOptionsSchema, \\n FileRemovalOptionsSchema,\\n ToolInvocationOptionsSchema,\\n ToolListingOptionsSchema \\n} from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n FileListingOptionsSchema,\\n FileRemovalOptionsSchema,\\n ToolInvocationOptionsSchema,\\n ToolListingOptionsSchema\\n ], 'src/zod_types.ts');\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\list.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { ListCommandSchema } from '../zod_schemas';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport type { Argv } from 'yargs';\\n\\nexport const options = (yargs: Argv) => toYargs(yargs, ListCommandSchema);\\n\\nexport const list = async (argv: any) => {\\n // Initialize tools with current directory\\n const fsTools = tools.fs(process.cwd());\\n const npmTools = tools.npm(process.cwd());\\n\\n const toolsList = {\\n fs: fsTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'fs'\\n })),\\n npm: npmTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'npm'\\n }))\\n };\\n\\n logger.info('Available Tools:\\\\n');\\n \\n logger.info('Filesystem Tools:');\\n fsTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nNPM Tools:');\\n npmTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n if (argv.output) {\\n logger.info(`\\\\nWriting tools list to ${argv.output}`);\\n write(argv.output, JSON.stringify(toolsList, null, 2));\\n }\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\invoke.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { InvokeToolSchema } from '../zod_schemas';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport type { Argv } from 'yargs';\\nimport * as path from 'path';\\n\\nconst options = (yargs: Argv) => toYargs(yargs, InvokeToolSchema);\\n\\nexport const invoke = async (argv: any) => {\\n try {\\n const { tools: toolCategory, function: funcName, target, params, output } = argv;\\n \\n // Get tool category\\n const toolSet = tools[toolCategory];\\n if (!toolSet) {\\n logger.error(`Tool category '${toolCategory}' not found`);\\n return;\\n }\\n\\n // Initialize tools with target directory\\n const toolList = toolSet(target);\\n \\n // Find specific function\\n const tool = toolList.find(t => t.function.name === funcName);\\n if (!tool) {\\n logger.error(`Function '${funcName}' not found in ${toolCategory} tools`);\\n return;\\n }\\n\\n // Parse parameters if provided\\n const parameters = params ? JSON.parse(params) : {};\\n \\n // Execute tool function\\n logger.info(`Invoking ${toolCategory}::${funcName}`);\\n const result = await tool.function.function(parameters);\\n \\n // Handle output\\n if (output) {\\n const outputPath = path.isAbsolute(output) ? output : path.join(process.cwd(), output);\\n logger.info(`Writing output to ${outputPath}`);\\n write(outputPath, JSON.stringify(result, null, 2));\\n } else {\\n logger.info('Result:', result);\\n }\\n \\n return result;\\n } catch (error) {\\n logger.error('Error invoking tool:', error);\\n throw error;\\n }\\n};\\n\\nexport { options as invokeOptions };\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\nimport { list, options as listOptions } from './list';\\nimport { invoke, invokeOptions } from './invoke';\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons';\\nimport { logger } from '../';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .command('list', 'List all available tools and their descriptions', listOptions, list)\\n .command('invoke', 'Invoke a specific tool function', invokeOptions, invoke)\\n .option('env_key', {\\n type: 'string',\\n description: 'Environment configuration key'\\n })\\n .middleware([(argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any;\\n if (!config) {\\n logger.warn('No config found!');\\n return;\\n }\\n return config;\\n }])\\n .strict()\\n .help();\\n};\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T13:01:18.638Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n### LLM Tools\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { resolve } from \"@plastichub/osr-commons\"\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any, variables:Record={}): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = path.resolve(resolve(join(target, file.path),false,variables))\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : 1. Add tools handling GIT related tasks: commit file(array,message), revert (files), switch to previous version (remote)\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\",\\n \\\"list\\\": \\\"ts-node src/main.ts list\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nA command-line interface and library for Language Model tools with filesystem operations support.\\n\\n## Prerequisites\\n\\n- Node.js >= 16\\n- pnpm (recommended) or npm\\n\\n## Installation\\n\\n```bash\\n# Install globally\\npnpm add -g llm-tools-cli\\n\\n# Or install in project\\npnpm add llm-tools-cli\\n```\\n\\n## Configuration\\n\\nCreate a configuration file or use environment variables:\\n\\n```json\\n{\\n \\\"openai\\\": {\\n \\\"key\\\": \\\"your-api-key\\\"\\n }\\n}\\n```\\n\\nOr use environment variable:\\n```bash\\nexport OPENAI_API_KEY=your-api-key\\n```\\n\\n## CLI Commands\\n\\n### Generate TypeScript Types\\n\\n```bash\\nllm-tools types\\n```\\n\\nGenerates TypeScript interfaces from all Zod schemas in the project.\\n\\n### List Available Tools\\n\\n```bash\\nllm-tools list [options]\\n\\nOptions:\\n --output Output file path [default: \\\"./llm-tools.json\\\"]\\n```\\n\\nLists all available tools and their descriptions.\\n\\n### Invoke Tool\\n\\n```bash\\nllm-tools invoke [options]\\n\\nOptions:\\n --tools Tool category (fs, npm)\\n --function Function name to invoke\\n --target Target directory [default: current]\\n --params JSON string of parameters\\n --output Output file path\\n --env_key Environment key\\n```\\n\\nExample:\\n```bash\\n# List files\\nllm-tools invoke --tools=fs --function=list_files \\\\\\n --params='{\\\"directory\\\":\\\"src\\\",\\\"pattern\\\":\\\"**/*.ts\\\"}'\\n\\n# Build project\\nllm-tools invoke --tools=npm --function=build_project\\n```\\n\\n## Library Usage\\n\\n### Filesystem Operations\\n\\n```typescript\\nimport { sync as rm } from '@plastichub/fs/remove'\\nimport { sync as dir } from '@plastichub/fs/dir'\\nimport { sync as write } from '@plastichub/fs/write'\\nimport { sync as read } from '@plastichub/fs/read'\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob'\\n\\n// Create directory\\ndir('path/to/dir')\\n\\n// Write file\\nwrite('file.txt', 'content')\\n\\n// Read file\\nconst content = read('file.txt')\\n\\n// Remove file/directory\\nrm('path/to/remove')\\n\\n// Find files\\nconst files = glob('src', ['**/*.ts'])\\n```\\n\\n### Logging\\n\\n```typescript\\nimport { Logger } from 'tslog'\\nimport { createLogger } from '@plastichub/osr-log'\\n\\nexport const logger: Logger = createLogger('package-name')\\n\\nlogger.info('Info message')\\nlogger.warn('Warning message')\\nlogger.error('Error message')\\n```\\n\\n### Configuration\\n\\n```typescript\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\\n\\nconst config = CONFIG_DEFAULT('env_key')\\nif (!config) {\\n logger.warn('No config found!')\\n return\\n}\\n\\nconst apiKey = config.openai?.key || process.env.OPENAI_API_KEY\\n```\\n\\n### Zod Schemas\\n\\n```typescript\\nimport { z } from 'zod'\\nimport { toYargs } from '@plastichub/osr-commons'\\n\\n// Define schema\\nconst MySchema = z.object({\\n field: z.string().describe('Description')\\n})\\n\\n// Convert to Yargs options\\nconst options = (yargs: Argv) => toYargs(yargs, MySchema)\\n```\\n\\n## Available Tools\\n\\n### Filesystem Tools\\n- list_files: List files in directory with pattern\\n- remove_file: Remove file at path\\n\\n### NPM Tools\\n- build_project: Build project using pnpm\\n\\n## Project Structure\\n\\n```\\nsrc/\\n├── index.ts # Logger setup\\n├── main.ts # CLI entry\\n├── constants.ts # Constants\\n├── tools.ts # Tool registry\\n├── zod_schemas.ts # Zod schemas\\n├── zod_types.ts # Generated types\\n├── commands/\\n│ ├── index.ts # Command registration\\n│ ├── list.ts # List command\\n│ ├── invoke.ts # Invoke command\\n│ └── types.ts # Types command\\n└── lib/\\n └── tools/\\n ├── fs.ts # Filesystem tools\\n └── npm.ts # NPM tools\\n```\\n\\n## Development\\n\\n```bash\\n# Build\\npnpm build\\n\\n# Run\\npnpm start\\n\\n# Development\\npnpm dev\\n\\n# Generate types\\npnpm types\\n```\\n\\n## Adding New Tools\\n\\n1. Add tool in `src/lib/tools/`\\n2. Register in `src/tools.ts`\\n3. Add schema in `src/zod_schemas.ts`\\n4. Run `pnpm types`\"\n },\n {\n \"path\": \"src\\\\zod_types.ts\",\n \"content\": \"export interface IOptions {\\n /** Directory path to list files from */\\n directory: string;\\n /** Glob pattern for filtering files */\\n pattern?: string | undefined;\\n}\\nexport interface IOptions {\\n /** Path of the file to remove */\\n path: string;\\n}\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\n/** Schema for listing files in a directory */\\nexport const FileListingOptionsSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n});\\n\\n/** Schema for file removal operations */\\nexport const FileRemovalOptionsSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n});\\n\\n/** Schema for tool invocation parameters */\\nexport const InvokeToolSchema = z.object({\\n tools: z.string().describe('Tool category to use (fs, npm)'),\\n function: z.string().describe('Function name to invoke'),\\n target: z.string().default(process.cwd()).describe('Target directory'),\\n params: z.string().optional().describe('JSON string of parameters'),\\n output: z.string().optional().describe('Path to write the output to'),\\n env_key: z.string().optional().describe('Environment configuration key')\\n});\\n\\n/** Schema for list command options */\\nexport const ListCommandSchema = z.object({\\n output: z.string().default(\\\"./llm-tools.json\\\").describe('Output file path for tools list')\\n});\\n\\n/** Schema for tool listing options */\\nexport const ToolListingOptionsSchema = z.object({\\n output: z.string().default('./llm-tools.json').describe('Output file path for tools list')\\n});\"\n },\n {\n \"path\": \"src\\\\tools.ts\",\n \"content\": \"import { tools as fsTools } from './lib/tools/fs';\\nimport { tools as npmTools } from './lib/tools/npm';\\n\\nexport const tools = {\\n fs: fsTools,\\n npm: npmTools\\n};\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport yargs from 'yargs';\\nimport { commands } from './commands';\\nimport { logger } from './';\\n\\nasync function main() {\\n try {\\n const argv = await commands(yargs).argv;\\n } catch (error) {\\n logger.error('Error executing command:', error);\\n process.exit(1);\\n }\\n}\\n\\nmain();\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\npm.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'build_project',\\n description: 'Build project using pnpm build command',\\n parameters: {\\n type: 'object',\\n properties: {},\\n required: []\\n },\\n function: async () => {\\n try {\\n logger.debug(`Tool::BuildProject Building project at ${target}`);\\n const { stdout, stderr } = await execAsync('pnpm build', {\\n cwd: target\\n });\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error : any) {\\n logger.error('Error building project', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { \\n FileListingOptionsSchema, \\n FileRemovalOptionsSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema \\n} from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n FileListingOptionsSchema,\\n FileRemovalOptionsSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema\\n ], 'src/zod_types.ts');\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\list.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { ListCommandSchema } from '../zod_schemas';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport type { Argv } from 'yargs';\\n\\nexport const options = (yargs: Argv) => toYargs(yargs, ListCommandSchema);\\n\\nexport const list = async (argv: any) => {\\n // Initialize tools with current directory\\n const fsTools = tools.fs(process.cwd());\\n const npmTools = tools.npm(process.cwd());\\n\\n const toolsList = {\\n fs: fsTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'fs'\\n })),\\n npm: npmTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'npm'\\n }))\\n };\\n\\n logger.info('Available Tools:\\\\n');\\n \\n logger.info('Filesystem Tools:');\\n fsTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nNPM Tools:');\\n npmTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n if (argv.output) {\\n logger.info(`\\\\nWriting tools list to ${argv.output}`);\\n write(argv.output, JSON.stringify(toolsList, null, 2));\\n }\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\invoke.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { InvokeToolSchema } from '../zod_schemas';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport type { Argv } from 'yargs';\\nimport * as path from 'path';\\n\\nconst options = (yargs: Argv) => toYargs(yargs, InvokeToolSchema);\\n\\nexport const invoke = async (argv: any) => {\\n try {\\n const { tools: toolCategory, function: funcName, target, params, output } = argv;\\n \\n // Get tool category\\n const toolSet = tools[toolCategory];\\n if (!toolSet) {\\n logger.error(`Tool category '${toolCategory}' not found`);\\n return;\\n }\\n\\n // Initialize tools with target directory\\n const toolList = toolSet(target);\\n \\n // Find specific function\\n const tool = toolList.find(t => t.function.name === funcName);\\n if (!tool) {\\n logger.error(`Function '${funcName}' not found in ${toolCategory} tools`);\\n return;\\n }\\n\\n // Parse parameters if provided\\n const parameters = params ? JSON.parse(params) : {};\\n \\n // Execute tool function\\n logger.info(`Invoking ${toolCategory}::${funcName}`);\\n const result = await tool.function.function(parameters);\\n \\n // Handle output\\n if (output) {\\n const outputPath = path.isAbsolute(output) ? output : path.join(process.cwd(), output);\\n logger.info(`Writing output to ${outputPath}`);\\n write(outputPath, JSON.stringify(result, null, 2));\\n } else {\\n logger.info('Result:', result);\\n }\\n \\n return result;\\n } catch (error) {\\n logger.error('Error invoking tool:', error);\\n throw error;\\n }\\n};\\n\\nexport { options as invokeOptions };\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\nimport { list, options as listOptions } from './list';\\nimport { invoke, invokeOptions } from './invoke';\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons';\\nimport { logger } from '../';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .command('list', 'List all available tools and their descriptions', listOptions, list)\\n .command('invoke', 'Invoke a specific tool function', invokeOptions, invoke)\\n .option('env_key', {\\n type: 'string',\\n description: 'Environment configuration key'\\n })\\n .middleware([(argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any;\\n if (!config) {\\n logger.warn('No config found!');\\n return;\\n }\\n return config;\\n }])\\n .strict()\\n .help();\\n};\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T13:05:24.881Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n### LLM Tools\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { resolve } from \"@plastichub/osr-commons\"\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any, variables:Record={}): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = path.resolve(resolve(join(target, file.path),false,variables))\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : 1. update GIT tools for using simple-git instead, catch all errors, return true if successful, otherwise errors\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\",\\n \\\"list\\\": \\\"ts-node src/main.ts list\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nA command-line interface and library for Language Model tools with filesystem, npm, and git operations support.\\n\\n## Prerequisites\\n\\n- Node.js >= 16\\n- pnpm (recommended) or npm\\n- Git (for git operations)\\n\\n## Installation\\n\\n```bash\\n# Install globally\\npnpm add -g llm-tools-cli\\n\\n# Or install in project\\npnpm add llm-tools-cli\\n```\\n\\n## Configuration\\n\\nCreate a configuration file or use environment variables:\\n\\n```json\\n{\\n \\\"openai\\\": {\\n \\\"key\\\": \\\"your-api-key\\\"\\n }\\n}\\n```\\n\\nOr use environment variable:\\n```bash\\nexport OPENAI_API_KEY=your-api-key\\n```\\n\\n## CLI Commands\\n\\n### Generate TypeScript Types\\n\\n```bash\\nllm-tools types\\n```\\n\\nGenerates TypeScript interfaces from all Zod schemas in the project.\\n\\n### List Available Tools\\n\\n```bash\\nllm-tools list [options]\\n\\nOptions:\\n --output Output file path [default: \\\"./llm-tools.json\\\"]\\n```\\n\\nLists all available tools and their descriptions.\\n\\n### Invoke Tool\\n\\n```bash\\nllm-tools invoke [options]\\n\\nOptions:\\n --tools Tool category (fs, npm, git)\\n --function Function name to invoke\\n --target Target directory [default: current]\\n --params JSON string of parameters\\n --output Output file path\\n --env_key Environment key\\n```\\n\\nExamples:\\n```bash\\n# List files\\nllm-tools invoke --tools=fs --function=list_files \\\\\\n --params='{\\\"directory\\\":\\\"src\\\",\\\"pattern\\\":\\\"**/*.ts\\\"}'\\n\\n# Build project\\nllm-tools invoke --tools=npm --function=build_project\\n\\n# Commit files\\nllm-tools invoke --tools=git --function=commit_files \\\\\\n --params='{\\\"files\\\":[\\\"src/main.ts\\\",\\\"package.json\\\"],\\\"message\\\":\\\"Update dependencies\\\"}'\\n\\n# Revert files\\nllm-tools invoke --tools=git --function=revert_files \\\\\\n --params='{\\\"files\\\":[\\\"src/config.ts\\\"]}'\\n\\n# Switch version\\nllm-tools invoke --tools=git --function=switch_version \\\\\\n --params='{\\\"branch\\\":\\\"main\\\",\\\"remote\\\":\\\"origin\\\"}'\\n```\\n\\n## Library Usage\\n\\n### Filesystem Operations\\n\\n```typescript\\nimport { sync as rm } from '@plastichub/fs/remove'\\nimport { sync as dir } from '@plastichub/fs/dir'\\nimport { sync as write } from '@plastichub/fs/write'\\nimport { sync as read } from '@plastichub/fs/read'\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob'\\n\\n// Create directory\\ndir('path/to/dir')\\n\\n// Write file\\nwrite('file.txt', 'content')\\n\\n// Read file\\nconst content = read('file.txt')\\n\\n// Remove file/directory\\nrm('path/to/remove')\\n\\n// Find files\\nconst files = glob('src', ['**/*.ts'])\\n```\\n\\n### Git Operations\\n\\n```typescript\\nimport { tools as gitTools } from './lib/tools/git'\\n\\nconst git = gitTools(process.cwd())\\n\\n// Commit files\\nawait git.find(t => t.function.name === 'commit_files').function.function({\\n files: ['src/main.ts', 'package.json'],\\n message: 'Update dependencies'\\n})\\n\\n// Revert files\\nawait git.find(t => t.function.name === 'revert_files').function.function({\\n files: ['src/config.ts']\\n})\\n\\n// Switch version\\nawait git.find(t => t.function.name === 'switch_version').function.function({\\n branch: 'main',\\n remote: 'origin'\\n})\\n```\\n\\n### Logging\\n\\n```typescript\\nimport { Logger } from 'tslog'\\nimport { createLogger } from '@plastichub/osr-log'\\n\\nexport const logger: Logger = createLogger('package-name')\\n\\nlogger.info('Info message')\\nlogger.warn('Warning message')\\nlogger.error('Error message')\\n```\\n\\n### Configuration\\n\\n```typescript\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\\n\\nconst config = CONFIG_DEFAULT('env_key')\\nif (!config) {\\n logger.warn('No config found!')\\n return\\n}\\n\\nconst apiKey = config.openai?.key || process.env.OPENAI_API_KEY\\n```\\n\\n### Zod Schemas\\n\\n```typescript\\nimport { z } from 'zod'\\nimport { toYargs } from '@plastichub/osr-commons'\\n\\n// Define schema\\nconst MySchema = z.object({\\n field: z.string().describe('Description')\\n})\\n\\n// Convert to Yargs options\\nconst options = (yargs: Argv) => toYargs(yargs, MySchema)\\n```\\n\\n## Available Tools\\n\\n### Filesystem Tools\\n- list_files: List files in directory with pattern\\n- remove_file: Remove file at path\\n\\n### NPM Tools\\n- build_project: Build project using pnpm\\n\\n### Git Tools\\n- commit_files: Commit files to git repository\\n- revert_files: Revert specified files in git repository\\n- switch_version: Switch to previous version from remote\\n\\n## Project Structure\\n\\n```\\nsrc/\\n├── index.ts # Logger setup\\n├── main.ts # CLI entry\\n├── constants.ts # Constants\\n├── tools.ts # Tool registry\\n├── zod_schemas.ts # Zod schemas\\n├── zod_types.ts # Generated types\\n├── commands/\\n│ ├── index.ts # Command registration\\n│ ├── list.ts # List command\\n│ ├── invoke.ts # Invoke command\\n│ └── types.ts # Types command\\n└── lib/\\n └── tools/\\n ├── fs.ts # Filesystem tools\\n ├── git.ts # Git tools\\n └── npm.ts # NPM tools\\n```\\n\\n## Development\\n\\n```bash\\n# Build\\npnpm build\\n\\n# Run\\npnpm start\\n\\n# Development\\npnpm dev\\n\\n# Generate types\\npnpm types\\n```\\n\\n## Adding New Tools\\n\\n1. Add tool in `src/lib/tools/`\\n2. Register in `src/tools.ts`\\n3. Add schema in `src/zod_schemas.ts`\\n4. Run `pnpm types`\"\n },\n {\n \"path\": \"src\\\\zod_types.ts\",\n \"content\": \"export interface IOptions {\\n /** Directory path to list files from */\\n directory: string;\\n /** Glob pattern for filtering files */\\n pattern?: string | undefined;\\n}\\nexport interface IOptions {\\n /** Path of the file to remove */\\n path: string;\\n}\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\n/** Schema for listing files in a directory */\\nexport const FileListingOptionsSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n});\\n\\n/** Schema for file removal operations */\\nexport const FileRemovalOptionsSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n});\\n\\n/** Schema for git commit operations */\\nexport const GitCommitSchema = z.object({\\n files: z.array(z.string()).describe('Files to commit'),\\n message: z.string().describe('Commit message')\\n});\\n\\n/** Schema for git revert operations */\\nexport const GitRevertSchema = z.object({\\n files: z.array(z.string()).describe('Files to revert')\\n});\\n\\n/** Schema for git version switch operations */\\nexport const GitSwitchVersionSchema = z.object({\\n branch: z.string().describe('Branch name to switch to'),\\n remote: z.string().default('origin').describe('Remote name')\\n});\\n\\n/** Schema for tool invocation parameters */\\nexport const InvokeToolSchema = z.object({\\n tools: z.string().describe('Tool category to use (fs, npm, git)'),\\n function: z.string().describe('Function name to invoke'),\\n target: z.string().default(process.cwd()).describe('Target directory'),\\n params: z.string().optional().describe('JSON string of parameters'),\\n output: z.string().optional().describe('Path to write the output to'),\\n env_key: z.string().optional().describe('Environment configuration key')\\n});\\n\\n/** Schema for list command options */\\nexport const ListCommandSchema = z.object({\\n output: z.string().default(\\\"./llm-tools.json\\\").describe('Output file path for tools list')\\n});\\n\\n/** Schema for tool listing options */\\nexport const ToolListingOptionsSchema = z.object({\\n output: z.string().default('./llm-tools.json').describe('Output file path for tools list')\\n});\"\n },\n {\n \"path\": \"src\\\\tools.ts\",\n \"content\": \"import { tools as fsTools } from './lib/tools/fs';\\nimport { tools as npmTools } from './lib/tools/npm';\\nimport { tools as gitTools } from './lib/tools/git';\\n\\nexport const tools = {\\n fs: fsTools,\\n npm: npmTools,\\n git: gitTools\\n};\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport yargs from 'yargs';\\nimport { commands } from './commands';\\nimport { logger } from './';\\n\\nasync function main() {\\n try {\\n const argv = await commands(yargs).argv;\\n } catch (error) {\\n logger.error('Error executing command:', error);\\n process.exit(1);\\n }\\n}\\n\\nmain();\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\npm.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'build_project',\\n description: 'Build project using pnpm build command',\\n parameters: {\\n type: 'object',\\n properties: {},\\n required: []\\n },\\n function: async () => {\\n try {\\n logger.debug(`Tool::BuildProject Building project at ${target}`);\\n const { stdout, stderr } = await execAsync('pnpm build', {\\n cwd: target\\n });\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error : any) {\\n logger.error('Error building project', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\git.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'commit_files',\\n description: 'Commit files to git repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n files: {\\n type: 'array',\\n items: { type: 'string' }\\n },\\n message: { type: 'string' }\\n },\\n required: ['files', 'message']\\n },\\n function: async (params: any) => {\\n try {\\n logger.debug(`Tool::Git Committing files with message: ${params.message}`);\\n // Add files\\n const filesStr = params.files.join(' ');\\n await execAsync(`git add ${filesStr}`, { cwd: target });\\n // Commit\\n const { stdout, stderr } = await execAsync(`git commit -m \\\"${params.message}\\\"`, { cwd: target });\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error: any) {\\n logger.error('Error committing files', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'revert_files',\\n description: 'Revert specified files in git repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n files: {\\n type: 'array',\\n items: { type: 'string' }\\n }\\n },\\n required: ['files']\\n },\\n function: async (params: any) => {\\n try {\\n const filesStr = params.files.join(' ');\\n logger.debug(`Tool::Git Reverting files: ${filesStr}`);\\n const { stdout, stderr } = await execAsync(`git checkout -- ${filesStr}`, { cwd: target });\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error: any) {\\n logger.error('Error reverting files', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'switch_version',\\n description: 'Switch to previous version from remote',\\n parameters: {\\n type: 'object',\\n properties: {\\n branch: { type: 'string' },\\n remote: { \\n type: 'string',\\n default: 'origin'\\n }\\n },\\n required: ['branch']\\n },\\n function: async (params: any) => {\\n try {\\n const remote = params.remote || 'origin';\\n logger.debug(`Tool::Git Switching to branch ${params.branch} from ${remote}`);\\n const { stdout, stderr } = await execAsync(`git checkout ${remote}/${params.branch}`, { cwd: target });\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error: any) {\\n logger.error('Error switching version', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { \\n FileListingOptionsSchema, \\n FileRemovalOptionsSchema,\\n GitCommitSchema,\\n GitRevertSchema,\\n GitSwitchVersionSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema \\n} from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n FileListingOptionsSchema,\\n FileRemovalOptionsSchema,\\n GitCommitSchema,\\n GitRevertSchema,\\n GitSwitchVersionSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema\\n ], 'src/zod_types.ts');\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\list.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { ListCommandSchema } from '../zod_schemas';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport type { Argv } from 'yargs';\\n\\nexport const options = (yargs: Argv) => toYargs(yargs, ListCommandSchema);\\n\\nexport const list = async (argv: any) => {\\n // Initialize tools with current directory\\n const fsTools = tools.fs(process.cwd());\\n const npmTools = tools.npm(process.cwd());\\n const gitTools = tools.git(process.cwd());\\n\\n const toolsList = {\\n fs: fsTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'fs'\\n })),\\n npm: npmTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'npm'\\n })),\\n git: gitTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'git'\\n }))\\n };\\n\\n logger.info('Available Tools:\\\\n');\\n \\n logger.info('Filesystem Tools:');\\n fsTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nNPM Tools:');\\n npmTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nGit Tools:');\\n gitTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n if (argv.output) {\\n logger.info(`\\\\nWriting tools list to ${argv.output}`);\\n write(argv.output, JSON.stringify(toolsList, null, 2));\\n }\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\invoke.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { InvokeToolSchema } from '../zod_schemas';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport type { Argv } from 'yargs';\\nimport * as path from 'path';\\n\\nconst options = (yargs: Argv) => toYargs(yargs, InvokeToolSchema);\\n\\nexport const invoke = async (argv: any) => {\\n try {\\n const { tools: toolCategory, function: funcName, target, params, output } = argv;\\n \\n // Get tool category\\n const toolSet = tools[toolCategory];\\n if (!toolSet) {\\n logger.error(`Tool category '${toolCategory}' not found`);\\n return;\\n }\\n\\n // Initialize tools with target directory\\n const toolList = toolSet(target);\\n \\n // Find specific function\\n const tool = toolList.find(t => t.function.name === funcName);\\n if (!tool) {\\n logger.error(`Function '${funcName}' not found in ${toolCategory} tools`);\\n return;\\n }\\n\\n // Parse parameters if provided\\n const parameters = params ? JSON.parse(params) : {};\\n \\n // Execute tool function\\n logger.info(`Invoking ${toolCategory}::${funcName}`);\\n const result = await tool.function.function(parameters);\\n \\n // Handle output\\n if (output) {\\n const outputPath = path.isAbsolute(output) ? output : path.join(process.cwd(), output);\\n logger.info(`Writing output to ${outputPath}`);\\n write(outputPath, JSON.stringify(result, null, 2));\\n } else {\\n logger.info('Result:', result);\\n }\\n \\n return result;\\n } catch (error) {\\n logger.error('Error invoking tool:', error);\\n throw error;\\n }\\n};\\n\\nexport { options as invokeOptions };\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\nimport { list, options as listOptions } from './list';\\nimport { invoke, invokeOptions } from './invoke';\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons';\\nimport { logger } from '../';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .command('list', 'List all available tools and their descriptions', listOptions, list)\\n .command('invoke', 'Invoke a specific tool function', invokeOptions, invoke)\\n .option('env_key', {\\n type: 'string',\\n description: 'Environment configuration key'\\n })\\n .middleware([(argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any;\\n if (!config) {\\n logger.warn('No config found!');\\n return;\\n }\\n return config;\\n }])\\n .strict()\\n .help();\\n};\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T13:08:01.624Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n### LLM Tools\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { resolve } from \"@plastichub/osr-commons\"\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any, variables:Record={}): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = path.resolve(resolve(join(target, file.path),false,variables))\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : Add another tool in tools/git : retrieve the raw version of a give file, allow single url, and repo & path\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\",\\n \\\"list\\\": \\\"ts-node src/main.ts list\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"simple-git\\\": \\\"^3.22.0\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nA command-line interface and library for Language Model tools with filesystem, npm, and git operations support.\\n\\n## Prerequisites\\n\\n- Node.js >= 16\\n- pnpm (recommended) or npm\\n- Git (for git operations)\\n\\n## Installation\\n\\n```bash\\n# Install globally\\npnpm add -g llm-tools-cli\\n\\n# Or install in project\\npnpm add llm-tools-cli\\n```\\n\\n## Quick Start\\n\\n```bash\\n# Generate TypeScript types\\nllm-tools types\\n\\n# List available tools\\nllm-tools list\\n\\n# Invoke a tool\\nllm-tools invoke --tools=fs --function=list_files --directory=src\\n```\\n\\n## Configuration\\n\\nCreate a configuration file or use environment variables:\\n\\n```json\\n{\\n \\\"openai\\\": {\\n \\\"key\\\": \\\"your-api-key\\\"\\n }\\n}\\n```\\n\\nOr use environment variable:\\n```bash\\nexport OPENAI_API_KEY=your-api-key\\n```\\n\\n## Available Commands\\n\\n### Generate TypeScript Types\\n\\n```bash\\nllm-tools types\\n```\\n\\nGenerates TypeScript interfaces from all Zod schemas in the project.\\n\\n### List Available Tools\\n\\n```bash\\nllm-tools list [options]\\n\\nOptions:\\n --output Output file path [default: \\\"./llm-tools.json\\\"]\\n```\\n\\nLists all available tools and their descriptions.\\n\\n### Invoke Tool\\n\\n```bash\\nllm-tools invoke [options]\\n\\nOptions:\\n --tools Tool category (fs, npm, git)\\n --function Function name to invoke\\n --target Target directory [default: current]\\n --params JSON string of parameters\\n --output Output file path\\n --env_key Environment key\\n```\\n\\n## Tool Categories and Functions\\n\\n### Filesystem Tools\\n\\n```typescript\\n// List files\\nllm-tools invoke --tools=fs --function=list_files \\\\\\n --params='{\\\"directory\\\":\\\"src\\\",\\\"pattern\\\":\\\"**/*.ts\\\"}'\\n\\n// Remove file\\nllm-tools invoke --tools=fs --function=remove_file \\\\\\n --params='{\\\"path\\\":\\\"temp.txt\\\"}'\\n```\\n\\n### Git Tools\\n\\n```typescript\\n// Commit files\\nllm-tools invoke --tools=git --function=commit_files \\\\\\n --params='{\\\"files\\\":[\\\"src/main.ts\\\"],\\\"message\\\":\\\"Update code\\\"}'\\n\\n// Revert files\\nllm-tools invoke --tools=git --function=revert_files \\\\\\n --params='{\\\"files\\\":[\\\"src/config.ts\\\"]}'\\n\\n// Switch version\\nllm-tools invoke --tools=git --function=switch_version \\\\\\n --params='{\\\"branch\\\":\\\"main\\\",\\\"remote\\\":\\\"origin\\\"}'\\n```\\n\\n### NPM Tools\\n\\n```typescript\\n// Build project\\nllm-tools invoke --tools=npm --function=build_project\\n```\\n\\n## Library Usage\\n\\n### Filesystem Operations\\n\\n```typescript\\nimport { sync as rm } from '@plastichub/fs/remove'\\nimport { sync as dir } from '@plastichub/fs/dir'\\nimport { sync as write } from '@plastichub/fs/write'\\nimport { sync as read } from '@plastichub/fs/read'\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob'\\n\\n// Create directory\\ndir('path/to/dir')\\n\\n// Write file\\nwrite('file.txt', 'content')\\n\\n// Read file\\nconst content = read('file.txt')\\n\\n// Remove file/directory\\nrm('path/to/remove')\\n\\n// Find files\\nconst files = glob('src', ['**/*.ts'])\\n```\\n\\n### Git Operations\\n\\n```typescript\\nimport { tools as gitTools } from './lib/tools/git'\\n\\nconst git = gitTools(process.cwd())\\n\\n// Commit files\\nawait git.find(t => t.function.name === 'commit_files')\\n .function.function({\\n files: ['src/main.ts'],\\n message: 'Update code'\\n })\\n\\n// Revert files\\nawait git.find(t => t.function.name === 'revert_files')\\n .function.function({\\n files: ['src/config.ts']\\n })\\n\\n// Switch version\\nawait git.find(t => t.function.name === 'switch_version')\\n .function.function({\\n branch: 'main',\\n remote: 'origin'\\n })\\n```\\n\\n### Logging\\n\\n```typescript\\nimport { Logger } from 'tslog'\\nimport { createLogger } from '@plastichub/osr-log'\\n\\nexport const logger: Logger = createLogger('package-name')\\n\\nlogger.info('Info message')\\nlogger.warn('Warning message')\\nlogger.error('Error message')\\n```\\n\\n### Configuration\\n\\n```typescript\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\\n\\nconst config = CONFIG_DEFAULT('env_key')\\nif (!config) {\\n logger.warn('No config found!')\\n return\\n}\\n\\nconst apiKey = config.openai?.key || process.env.OPENAI_API_KEY\\n```\\n\\n### Zod Schemas and Types\\n\\n```typescript\\nimport { z } from 'zod'\\nimport { toYargs } from '@plastichub/osr-commons'\\n\\n// Define schema\\nconst MySchema = z.object({\\n field: z.string().describe('Description')\\n})\\n\\n// Convert to Yargs options\\nconst options = (yargs: Argv) => toYargs(yargs, MySchema)\\n\\n// Generate types\\nllm-tools types\\n```\\n\\n## Development\\n\\n```bash\\n# Clone repository\\ngit clone \\ncd llm-tools-cli\\n\\n# Install dependencies\\npnpm install\\n\\n# Build\\npnpm build\\n\\n# Run development version\\npnpm dev\\n\\n# Generate types\\npnpm types\\n```\\n\\n## Project Structure\\n\\n```\\nsrc/\\n├── index.ts # Logger setup\\n├── main.ts # CLI entry\\n├── constants.ts # Constants\\n├── tools.ts # Tool registry\\n├── zod_schemas.ts # Zod schemas\\n├── zod_types.ts # Generated types\\n├── commands/\\n│ ├── index.ts # Command registration\\n│ ├── list.ts # List command\\n│ ├── invoke.ts # Invoke command\\n│ └── types.ts # Types command\\n└── lib/\\n └── tools/\\n ├── fs.ts # Filesystem tools\\n ├── git.ts # Git tools\\n └── npm.ts # NPM tools\\n```\\n\"\n },\n {\n \"path\": \"src\\\\zod_types.ts\",\n \"content\": \"export interface IOptions {\\n /** Directory path to list files from */\\n directory: string;\\n /** Glob pattern for filtering files */\\n pattern?: string | undefined;\\n}\\nexport interface IOptions {\\n /** Path of the file to remove */\\n path: string;\\n}\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\n/** Schema for listing files in a directory */\\nexport const FileListingOptionsSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n});\\n\\n/** Schema for file removal operations */\\nexport const FileRemovalOptionsSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n});\\n\\n/** Schema for git commit operations */\\nexport const GitCommitSchema = z.object({\\n files: z.array(z.string()).describe('Files to commit'),\\n message: z.string().describe('Commit message')\\n});\\n\\n/** Schema for git revert operations */\\nexport const GitRevertSchema = z.object({\\n files: z.array(z.string()).describe('Files to revert')\\n});\\n\\n/** Schema for git version switch operations */\\nexport const GitSwitchVersionSchema = z.object({\\n branch: z.string().describe('Branch name to switch to'),\\n remote: z.string().default('origin').describe('Remote name')\\n});\\n\\n/** Schema for tool invocation parameters */\\nexport const InvokeToolSchema = z.object({\\n tools: z.string().describe('Tool category to use (fs, npm, git)'),\\n function: z.string().describe('Function name to invoke'),\\n target: z.string().default(process.cwd()).describe('Target directory'),\\n params: z.string().optional().describe('JSON string of parameters'),\\n output: z.string().optional().describe('Path to write the output to'),\\n env_key: z.string().optional().describe('Environment configuration key')\\n});\\n\\n/** Schema for list command options */\\nexport const ListCommandSchema = z.object({\\n output: z.string().default(\\\"./llm-tools.json\\\").describe('Output file path for tools list')\\n});\\n\\n/** Schema for tool listing options */\\nexport const ToolListingOptionsSchema = z.object({\\n output: z.string().default('./llm-tools.json').describe('Output file path for tools list')\\n});\"\n },\n {\n \"path\": \"src\\\\tools.ts\",\n \"content\": \"import { tools as fsTools } from './lib/tools/fs';\\nimport { tools as npmTools } from './lib/tools/npm';\\nimport { tools as gitTools } from './lib/tools/git';\\n\\nexport const tools = {\\n fs: fsTools,\\n npm: npmTools,\\n git: gitTools\\n};\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport yargs from 'yargs';\\nimport { commands } from './commands';\\nimport { logger } from './';\\n\\nasync function main() {\\n try {\\n const argv = await commands(yargs).argv;\\n } catch (error) {\\n logger.error('Error executing command:', error);\\n process.exit(1);\\n }\\n}\\n\\nmain();\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\npm.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'build_project',\\n description: 'Build project using pnpm build command',\\n parameters: {\\n type: 'object',\\n properties: {},\\n required: []\\n },\\n function: async () => {\\n try {\\n logger.debug(`Tool::BuildProject Building project at ${target}`);\\n const { stdout, stderr } = await execAsync('pnpm build', {\\n cwd: target\\n });\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error : any) {\\n logger.error('Error building project', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\git.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport simpleGit, { SimpleGit } from 'simple-git';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n const git: SimpleGit = simpleGit(target);\\n\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'commit_files',\\n description: 'Commit files to git repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n files: {\\n type: 'array',\\n items: { type: 'string' }\\n },\\n message: { type: 'string' }\\n },\\n required: ['files', 'message']\\n },\\n function: async (params: any) => {\\n try {\\n logger.debug(`Tool::Git Committing files with message: ${params.message}`);\\n await git.add(params.files);\\n const result = await git.commit(params.message);\\n return {\\n success: true,\\n output: result,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error committing files', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'revert_files',\\n description: 'Revert specified files in git repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n files: {\\n type: 'array',\\n items: { type: 'string' }\\n }\\n },\\n required: ['files']\\n },\\n function: async (params: any) => {\\n try {\\n logger.debug(`Tool::Git Reverting files: ${params.files.join(', ')}`);\\n await git.checkout(['--', ...params.files]);\\n return {\\n success: true,\\n output: 'Files reverted successfully',\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error reverting files', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'switch_version',\\n description: 'Switch to previous version from remote',\\n parameters: {\\n type: 'object',\\n properties: {\\n branch: { type: 'string' },\\n remote: { \\n type: 'string',\\n default: 'origin'\\n }\\n },\\n required: ['branch']\\n },\\n function: async (params: any) => {\\n try {\\n const remote = params.remote || 'origin';\\n logger.debug(`Tool::Git Switching to branch ${params.branch} from ${remote}`);\\n const result = await git.checkout(`${remote}/${params.branch}`);\\n return {\\n success: true,\\n output: result,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error switching version', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { \\n FileListingOptionsSchema, \\n FileRemovalOptionsSchema,\\n GitCommitSchema,\\n GitRevertSchema,\\n GitSwitchVersionSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema \\n} from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n FileListingOptionsSchema,\\n FileRemovalOptionsSchema,\\n GitCommitSchema,\\n GitRevertSchema,\\n GitSwitchVersionSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema\\n ], 'src/zod_types.ts');\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\list.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { ListCommandSchema } from '../zod_schemas';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport type { Argv } from 'yargs';\\n\\nexport const options = (yargs: Argv) => toYargs(yargs, ListCommandSchema);\\n\\nexport const list = async (argv: any) => {\\n // Initialize tools with current directory\\n const fsTools = tools.fs(process.cwd());\\n const npmTools = tools.npm(process.cwd());\\n const gitTools = tools.git(process.cwd());\\n\\n const toolsList = {\\n fs: fsTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'fs'\\n })),\\n npm: npmTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'npm'\\n })),\\n git: gitTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'git'\\n }))\\n };\\n\\n logger.info('Available Tools:\\\\n');\\n \\n logger.info('Filesystem Tools:');\\n fsTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nNPM Tools:');\\n npmTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nGit Tools:');\\n gitTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n if (argv.output) {\\n logger.info(`\\\\nWriting tools list to ${argv.output}`);\\n write(argv.output, JSON.stringify(toolsList, null, 2));\\n }\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\invoke.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { InvokeToolSchema } from '../zod_schemas';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport type { Argv } from 'yargs';\\nimport * as path from 'path';\\n\\nconst options = (yargs: Argv) => toYargs(yargs, InvokeToolSchema);\\n\\nexport const invoke = async (argv: any) => {\\n try {\\n const { tools: toolCategory, function: funcName, target, params, output } = argv;\\n \\n // Get tool category\\n const toolSet = tools[toolCategory];\\n if (!toolSet) {\\n logger.error(`Tool category '${toolCategory}' not found`);\\n return;\\n }\\n\\n // Initialize tools with target directory\\n const toolList = toolSet(target);\\n \\n // Find specific function\\n const tool = toolList.find(t => t.function.name === funcName);\\n if (!tool) {\\n logger.error(`Function '${funcName}' not found in ${toolCategory} tools`);\\n return;\\n }\\n\\n // Parse parameters if provided\\n const parameters = params ? JSON.parse(params) : {};\\n \\n // Execute tool function\\n logger.info(`Invoking ${toolCategory}::${funcName}`);\\n const result = await tool.function.function(parameters);\\n \\n // Handle output\\n if (output) {\\n const outputPath = path.isAbsolute(output) ? output : path.join(process.cwd(), output);\\n logger.info(`Writing output to ${outputPath}`);\\n write(outputPath, JSON.stringify(result, null, 2));\\n } else {\\n logger.info('Result:', result);\\n }\\n \\n return result;\\n } catch (error) {\\n logger.error('Error invoking tool:', error);\\n throw error;\\n }\\n};\\n\\nexport { options as invokeOptions };\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\nimport { list, options as listOptions } from './list';\\nimport { invoke, invokeOptions } from './invoke';\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons';\\nimport { logger } from '../';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .command('list', 'List all available tools and their descriptions', listOptions, list)\\n .command('invoke', 'Invoke a specific tool function', invokeOptions, invoke)\\n .option('env_key', {\\n type: 'string',\\n description: 'Environment configuration key'\\n })\\n .middleware([(argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any;\\n if (!config) {\\n logger.warn('No config found!');\\n return;\\n }\\n return config;\\n }])\\n .strict()\\n .help();\\n};\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T13:14:35.670Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n### LLM Tools\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { resolve } from \"@plastichub/osr-commons\"\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any, variables:Record={}): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = path.resolve(resolve(join(target, file.path),false,variables))\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : Add another tool in tools/npm : run npm command, return true if successful, or list of errors\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\",\\n \\\"list\\\": \\\"ts-node src/main.ts list\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"simple-git\\\": \\\"^3.22.0\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nA command-line interface and library for Language Model tools with filesystem, npm, and git operations support.\\n\\n## Prerequisites\\n\\n- Node.js >= 16\\n- pnpm (recommended) or npm\\n- Git (for git operations)\\n\\n## Installation\\n\\n```bash\\n# Install globally\\npnpm add -g llm-tools-cli\\n\\n# Or install in project\\npnpm add llm-tools-cli\\n```\\n\\n## Quick Start\\n\\n```bash\\n# Generate TypeScript types\\nllm-tools types\\n\\n# List available tools\\nllm-tools list\\n\\n# Invoke a tool\\nllm-tools invoke --tools=fs --function=list_files --directory=src\\n```\\n\\n## Configuration\\n\\nCreate a configuration file or use environment variables:\\n\\n```json\\n{\\n \\\"openai\\\": {\\n \\\"key\\\": \\\"your-api-key\\\"\\n }\\n}\\n```\\n\\nOr use environment variable:\\n```bash\\nexport OPENAI_API_KEY=your-api-key\\n```\\n\\n## Available Commands\\n\\n### Generate TypeScript Types\\n\\n```bash\\nllm-tools types\\n```\\n\\nGenerates TypeScript interfaces from all Zod schemas in the project.\\n\\n### List Available Tools\\n\\n```bash\\nllm-tools list [options]\\n\\nOptions:\\n --output Output file path [default: \\\"./llm-tools.json\\\"]\\n```\\n\\nLists all available tools and their descriptions.\\n\\n### Invoke Tool\\n\\n```bash\\nllm-tools invoke [options]\\n\\nOptions:\\n --tools Tool category (fs, npm, git)\\n --function Function name to invoke\\n --target Target directory [default: current]\\n --params JSON string of parameters\\n --output Output file path\\n --env_key Environment key\\n```\\n\\n## Tool Categories and Functions\\n\\n### Filesystem Tools\\n\\n```typescript\\n// List files\\nllm-tools invoke --tools=fs --function=list_files \\\\\\n --params='{\\\"directory\\\":\\\"src\\\",\\\"pattern\\\":\\\"**/*.ts\\\"}'\\n\\n// Remove file\\nllm-tools invoke --tools=fs --function=remove_file \\\\\\n --params='{\\\"path\\\":\\\"temp.txt\\\"}'\\n```\\n\\n### Git Tools\\n\\n```typescript\\n// Commit files\\nllm-tools invoke --tools=git --function=commit_files \\\\\\n --params='{\\\"files\\\":[\\\"src/main.ts\\\"],\\\"message\\\":\\\"Update code\\\"}'\\n\\n// Revert files\\nllm-tools invoke --tools=git --function=revert_files \\\\\\n --params='{\\\"files\\\":[\\\"src/config.ts\\\"]}'\\n\\n// Switch version\\nllm-tools invoke --tools=git --function=switch_version \\\\\\n --params='{\\\"branch\\\":\\\"main\\\",\\\"remote\\\":\\\"origin\\\"}'\\n```\\n\\n### NPM Tools\\n\\n```typescript\\n// Build project\\nllm-tools invoke --tools=npm --function=build_project\\n```\\n\\n## Library Usage\\n\\n### Filesystem Operations\\n\\n```typescript\\nimport { sync as rm } from '@plastichub/fs/remove'\\nimport { sync as dir } from '@plastichub/fs/dir'\\nimport { sync as write } from '@plastichub/fs/write'\\nimport { sync as read } from '@plastichub/fs/read'\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob'\\n\\n// Create directory\\ndir('path/to/dir')\\n\\n// Write file\\nwrite('file.txt', 'content')\\n\\n// Read file\\nconst content = read('file.txt')\\n\\n// Remove file/directory\\nrm('path/to/remove')\\n\\n// Find files\\nconst files = glob('src', ['**/*.ts'])\\n```\\n\\n### Git Operations\\n\\n```typescript\\nimport { tools as gitTools } from './lib/tools/git'\\n\\nconst git = gitTools(process.cwd())\\n\\n// Commit files\\nawait git.find(t => t.function.name === 'commit_files')\\n .function.function({\\n files: ['src/main.ts'],\\n message: 'Update code'\\n })\\n\\n// Revert files\\nawait git.find(t => t.function.name === 'revert_files')\\n .function.function({\\n files: ['src/config.ts']\\n })\\n\\n// Switch version\\nawait git.find(t => t.function.name === 'switch_version')\\n .function.function({\\n branch: 'main',\\n remote: 'origin'\\n })\\n```\\n\\n### Logging\\n\\n```typescript\\nimport { Logger } from 'tslog'\\nimport { createLogger } from '@plastichub/osr-log'\\n\\nexport const logger: Logger = createLogger('package-name')\\n\\nlogger.info('Info message')\\nlogger.warn('Warning message')\\nlogger.error('Error message')\\n```\\n\\n### Configuration\\n\\n```typescript\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\\n\\nconst config = CONFIG_DEFAULT('env_key')\\nif (!config) {\\n logger.warn('No config found!')\\n return\\n}\\n\\nconst apiKey = config.openai?.key || process.env.OPENAI_API_KEY\\n```\\n\\n### Zod Schemas and Types\\n\\n```typescript\\nimport { z } from 'zod'\\nimport { toYargs } from '@plastichub/osr-commons'\\n\\n// Define schema\\nconst MySchema = z.object({\\n field: z.string().describe('Description')\\n})\\n\\n// Convert to Yargs options\\nconst options = (yargs: Argv) => toYargs(yargs, MySchema)\\n\\n// Generate types\\nllm-tools types\\n```\\n\\n## Development\\n\\n```bash\\n# Clone repository\\ngit clone \\ncd llm-tools-cli\\n\\n# Install dependencies\\npnpm install\\n\\n# Build\\npnpm build\\n\\n# Run development version\\npnpm dev\\n\\n# Generate types\\npnpm types\\n```\\n\\n## Project Structure\\n\\n```\\nsrc/\\n├── index.ts # Logger setup\\n├── main.ts # CLI entry\\n├── constants.ts # Constants\\n├── tools.ts # Tool registry\\n├── zod_schemas.ts # Zod schemas\\n├── zod_types.ts # Generated types\\n├── commands/\\n│ ├── index.ts # Command registration\\n│ ├── list.ts # List command\\n│ ├── invoke.ts # Invoke command\\n│ └── types.ts # Types command\\n└── lib/\\n └── tools/\\n ├── fs.ts # Filesystem tools\\n ├── git.ts # Git tools\\n └── npm.ts # NPM tools\\n```\\n\"\n },\n {\n \"path\": \"src\\\\zod_types.ts\",\n \"content\": \"export interface IOptions {\\n /** Directory path to list files from */\\n directory: string;\\n /** Glob pattern for filtering files */\\n pattern?: string | undefined;\\n}\\nexport interface IOptions {\\n /** Path of the file to remove */\\n path: string;\\n}\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\n/** Schema for listing files in a directory */\\nexport const FileListingOptionsSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n});\\n\\n/** Schema for file removal operations */\\nexport const FileRemovalOptionsSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n});\\n\\n/** Schema for git commit operations */\\nexport const GitCommitSchema = z.object({\\n files: z.array(z.string()).describe('Files to commit'),\\n message: z.string().describe('Commit message')\\n});\\n\\n/** Schema for git revert operations */\\nexport const GitRevertSchema = z.object({\\n files: z.array(z.string()).describe('Files to revert')\\n});\\n\\n/** Schema for git version switch operations */\\nexport const GitSwitchVersionSchema = z.object({\\n branch: z.string().describe('Branch name to switch to'),\\n remote: z.string().default('origin').describe('Remote name')\\n});\\n\\n/** Schema for git raw file retrieval */\\nexport const GitRawFileSchema = z.object({\\n url: z.string().optional().describe('Full GitHub raw URL'),\\n repo: z.string().optional().describe('Repository in format owner/repo'),\\n path: z.string().optional().describe('File path within repository')\\n}).refine(\\n data => (data.url) || (data.repo && data.path),\\n 'Either url or both repo and path must be provided'\\n);\\n\\n/** Schema for tool invocation parameters */\\nexport const InvokeToolSchema = z.object({\\n tools: z.string().describe('Tool category to use (fs, npm, git)'),\\n function: z.string().describe('Function name to invoke'),\\n target: z.string().default(process.cwd()).describe('Target directory'),\\n params: z.string().optional().describe('JSON string of parameters'),\\n output: z.string().optional().describe('Path to write the output to'),\\n env_key: z.string().optional().describe('Environment configuration key')\\n});\\n\\n/** Schema for list command options */\\nexport const ListCommandSchema = z.object({\\n output: z.string().default(\\\"./llm-tools.json\\\").describe('Output file path for tools list')\\n});\\n\\n/** Schema for tool listing options */\\nexport const ToolListingOptionsSchema = z.object({\\n output: z.string().default('./llm-tools.json').describe('Output file path for tools list')\\n});\"\n },\n {\n \"path\": \"src\\\\tools.ts\",\n \"content\": \"import { tools as fsTools } from './lib/tools/fs';\\nimport { tools as npmTools } from './lib/tools/npm';\\nimport { tools as gitTools } from './lib/tools/git';\\n\\nexport const tools = {\\n fs: fsTools,\\n npm: npmTools,\\n git: gitTools\\n};\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport yargs from 'yargs';\\nimport { commands } from './commands';\\nimport { logger } from './';\\n\\nasync function main() {\\n try {\\n const argv = await commands(yargs).argv;\\n } catch (error) {\\n logger.error('Error executing command:', error);\\n process.exit(1);\\n }\\n}\\n\\nmain();\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\npm.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'build_project',\\n description: 'Build project using pnpm build command',\\n parameters: {\\n type: 'object',\\n properties: {},\\n required: []\\n },\\n function: async () => {\\n try {\\n logger.debug(`Tool::BuildProject Building project at ${target}`);\\n const { stdout, stderr } = await execAsync('pnpm build', {\\n cwd: target\\n });\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error : any) {\\n logger.error('Error building project', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\git.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport simpleGit, { SimpleGit } from 'simple-git';\\nimport axios from 'axios';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n const git: SimpleGit = simpleGit(target);\\n\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'commit_files',\\n description: 'Commit files to git repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n files: {\\n type: 'array',\\n items: { type: 'string' }\\n },\\n message: { type: 'string' }\\n },\\n required: ['files', 'message']\\n },\\n function: async (params: any) => {\\n try {\\n logger.debug(`Tool::Git Committing files with message: ${params.message}`);\\n await git.add(params.files);\\n const result = await git.commit(params.message);\\n return {\\n success: true,\\n output: result,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error committing files', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'revert_files',\\n description: 'Revert specified files in git repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n files: {\\n type: 'array',\\n items: { type: 'string' }\\n }\\n },\\n required: ['files']\\n },\\n function: async (params: any) => {\\n try {\\n logger.debug(`Tool::Git Reverting files: ${params.files.join(', ')}`);\\n await git.checkout(['--', ...params.files]);\\n return {\\n success: true,\\n output: 'Files reverted successfully',\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error reverting files', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'switch_version',\\n description: 'Switch to previous version from remote',\\n parameters: {\\n type: 'object',\\n properties: {\\n branch: { type: 'string' },\\n remote: { \\n type: 'string',\\n default: 'origin'\\n }\\n },\\n required: ['branch']\\n },\\n function: async (params: any) => {\\n try {\\n const remote = params.remote || 'origin';\\n logger.debug(`Tool::Git Switching to branch ${params.branch} from ${remote}`);\\n const result = await git.checkout(`${remote}/${params.branch}`);\\n return {\\n success: true,\\n output: result,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error switching version', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'get_raw_file',\\n description: 'Retrieve raw content of a file from GitHub repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n url: { \\n type: 'string',\\n description: 'Full GitHub raw URL or repository path'\\n },\\n repo: {\\n type: 'string',\\n description: 'Repository in format owner/repo'\\n },\\n path: {\\n type: 'string',\\n description: 'File path within repository'\\n }\\n },\\n oneOf: [\\n { required: ['url'] },\\n { required: ['repo', 'path'] }\\n ]\\n },\\n function: async (params: any) => {\\n try {\\n let fileUrl = params.url;\\n if (!fileUrl && params.repo && params.path) {\\n fileUrl = `https://raw.githubusercontent.com/${params.repo}/main/${params.path}`;\\n }\\n \\n logger.debug(`Tool::Git Fetching raw file from ${fileUrl}`);\\n const response = await axios.get(fileUrl);\\n return {\\n success: true,\\n content: response.data,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error fetching raw file', error);\\n return {\\n success: false,\\n content: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { \\n FileListingOptionsSchema, \\n FileRemovalOptionsSchema,\\n GitCommitSchema,\\n GitRevertSchema,\\n GitSwitchVersionSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema \\n} from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n FileListingOptionsSchema,\\n FileRemovalOptionsSchema,\\n GitCommitSchema,\\n GitRevertSchema,\\n GitSwitchVersionSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema\\n ], 'src/zod_types.ts');\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\list.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { ListCommandSchema } from '../zod_schemas';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport type { Argv } from 'yargs';\\n\\nexport const options = (yargs: Argv) => toYargs(yargs, ListCommandSchema);\\n\\nexport const list = async (argv: any) => {\\n // Initialize tools with current directory\\n const fsTools = tools.fs(process.cwd());\\n const npmTools = tools.npm(process.cwd());\\n const gitTools = tools.git(process.cwd());\\n\\n const toolsList = {\\n fs: fsTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'fs'\\n })),\\n npm: npmTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'npm'\\n })),\\n git: gitTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'git'\\n }))\\n };\\n\\n logger.info('Available Tools:\\\\n');\\n \\n logger.info('Filesystem Tools:');\\n fsTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nNPM Tools:');\\n npmTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nGit Tools:');\\n gitTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n if (argv.output) {\\n logger.info(`\\\\nWriting tools list to ${argv.output}`);\\n write(argv.output, JSON.stringify(toolsList, null, 2));\\n }\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\invoke.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { InvokeToolSchema } from '../zod_schemas';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport type { Argv } from 'yargs';\\nimport * as path from 'path';\\n\\nconst options = (yargs: Argv) => toYargs(yargs, InvokeToolSchema);\\n\\nexport const invoke = async (argv: any) => {\\n try {\\n const { tools: toolCategory, function: funcName, target, params, output } = argv;\\n \\n // Get tool category\\n const toolSet = tools[toolCategory];\\n if (!toolSet) {\\n logger.error(`Tool category '${toolCategory}' not found`);\\n return;\\n }\\n\\n // Initialize tools with target directory\\n const toolList = toolSet(target);\\n \\n // Find specific function\\n const tool = toolList.find(t => t.function.name === funcName);\\n if (!tool) {\\n logger.error(`Function '${funcName}' not found in ${toolCategory} tools`);\\n return;\\n }\\n\\n // Parse parameters if provided\\n const parameters = params ? JSON.parse(params) : {};\\n \\n // Execute tool function\\n logger.info(`Invoking ${toolCategory}::${funcName}`);\\n const result = await tool.function.function(parameters);\\n \\n // Handle output\\n if (output) {\\n const outputPath = path.isAbsolute(output) ? output : path.join(process.cwd(), output);\\n logger.info(`Writing output to ${outputPath}`);\\n write(outputPath, JSON.stringify(result, null, 2));\\n } else {\\n logger.info('Result:', result);\\n }\\n \\n return result;\\n } catch (error) {\\n logger.error('Error invoking tool:', error);\\n throw error;\\n }\\n};\\n\\nexport { options as invokeOptions };\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\nimport { list, options as listOptions } from './list';\\nimport { invoke, invokeOptions } from './invoke';\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons';\\nimport { logger } from '../';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .command('list', 'List all available tools and their descriptions', listOptions, list)\\n .command('invoke', 'Invoke a specific tool function', invokeOptions, invoke)\\n .option('env_key', {\\n type: 'string',\\n description: 'Environment configuration key'\\n })\\n .middleware([(argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any;\\n if (!config) {\\n logger.warn('No config found!');\\n return;\\n }\\n return config;\\n }])\\n .strict()\\n .help();\\n};\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T13:17:02.919Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n### LLM Tools\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { resolve } from \"@plastichub/osr-commons\"\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any, variables:Record={}): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = path.resolve(resolve(join(target, file.path),false,variables))\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : Add another tool in tools/terminal : execute command (cmd, args), capture all output\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\",\\n \\\"list\\\": \\\"ts-node src/main.ts list\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"simple-git\\\": \\\"^3.22.0\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nA command-line interface and library for Language Model tools with filesystem, npm, and git operations support.\\n\\n## Prerequisites\\n\\n- Node.js >= 16\\n- pnpm (recommended) or npm\\n- Git (for git operations)\\n\\n## Installation\\n\\n```bash\\n# Install globally\\npnpm add -g llm-tools-cli\\n\\n# Or install in project\\npnpm add llm-tools-cli\\n```\\n\\n## Quick Start\\n\\n```bash\\n# Generate TypeScript types\\nllm-tools types\\n\\n# List available tools\\nllm-tools list\\n\\n# Invoke a tool\\nllm-tools invoke --tools=fs --function=list_files --directory=src\\n```\\n\\n## Configuration\\n\\nCreate a configuration file or use environment variables:\\n\\n```json\\n{\\n \\\"openai\\\": {\\n \\\"key\\\": \\\"your-api-key\\\"\\n }\\n}\\n```\\n\\nOr use environment variable:\\n```bash\\nexport OPENAI_API_KEY=your-api-key\\n```\\n\\n## Available Commands\\n\\n### Generate TypeScript Types\\n\\n```bash\\nllm-tools types\\n```\\n\\nGenerates TypeScript interfaces from all Zod schemas in the project.\\n\\n### List Available Tools\\n\\n```bash\\nllm-tools list [options]\\n\\nOptions:\\n --output Output file path [default: \\\"./llm-tools.json\\\"]\\n```\\n\\nLists all available tools and their descriptions.\\n\\n### Invoke Tool\\n\\n```bash\\nllm-tools invoke [options]\\n\\nOptions:\\n --tools Tool category (fs, npm, git)\\n --function Function name to invoke\\n --target Target directory [default: current]\\n --params JSON string of parameters\\n --output Output file path\\n --env_key Environment key\\n```\\n\\n## Tool Categories and Functions\\n\\n### Filesystem Tools\\n\\n```typescript\\n// List files\\nllm-tools invoke --tools=fs --function=list_files \\\\\\n --params='{\\\"directory\\\":\\\"src\\\",\\\"pattern\\\":\\\"**/*.ts\\\"}'\\n\\n// Remove file\\nllm-tools invoke --tools=fs --function=remove_file \\\\\\n --params='{\\\"path\\\":\\\"temp.txt\\\"}'\\n```\\n\\n### Git Tools\\n\\n```typescript\\n// Commit files\\nllm-tools invoke --tools=git --function=commit_files \\\\\\n --params='{\\\"files\\\":[\\\"src/main.ts\\\"],\\\"message\\\":\\\"Update code\\\"}'\\n\\n// Revert files\\nllm-tools invoke --tools=git --function=revert_files \\\\\\n --params='{\\\"files\\\":[\\\"src/config.ts\\\"]}'\\n\\n// Switch version\\nllm-tools invoke --tools=git --function=switch_version \\\\\\n --params='{\\\"branch\\\":\\\"main\\\",\\\"remote\\\":\\\"origin\\\"}'\\n```\\n\\n### NPM Tools\\n\\n```typescript\\n// Build project\\nllm-tools invoke --tools=npm --function=build_project\\n```\\n\\n## Library Usage\\n\\n### Filesystem Operations\\n\\n```typescript\\nimport { sync as rm } from '@plastichub/fs/remove'\\nimport { sync as dir } from '@plastichub/fs/dir'\\nimport { sync as write } from '@plastichub/fs/write'\\nimport { sync as read } from '@plastichub/fs/read'\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob'\\n\\n// Create directory\\ndir('path/to/dir')\\n\\n// Write file\\nwrite('file.txt', 'content')\\n\\n// Read file\\nconst content = read('file.txt')\\n\\n// Remove file/directory\\nrm('path/to/remove')\\n\\n// Find files\\nconst files = glob('src', ['**/*.ts'])\\n```\\n\\n### Git Operations\\n\\n```typescript\\nimport { tools as gitTools } from './lib/tools/git'\\n\\nconst git = gitTools(process.cwd())\\n\\n// Commit files\\nawait git.find(t => t.function.name === 'commit_files')\\n .function.function({\\n files: ['src/main.ts'],\\n message: 'Update code'\\n })\\n\\n// Revert files\\nawait git.find(t => t.function.name === 'revert_files')\\n .function.function({\\n files: ['src/config.ts']\\n })\\n\\n// Switch version\\nawait git.find(t => t.function.name === 'switch_version')\\n .function.function({\\n branch: 'main',\\n remote: 'origin'\\n })\\n```\\n\\n### Logging\\n\\n```typescript\\nimport { Logger } from 'tslog'\\nimport { createLogger } from '@plastichub/osr-log'\\n\\nexport const logger: Logger = createLogger('package-name')\\n\\nlogger.info('Info message')\\nlogger.warn('Warning message')\\nlogger.error('Error message')\\n```\\n\\n### Configuration\\n\\n```typescript\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\\n\\nconst config = CONFIG_DEFAULT('env_key')\\nif (!config) {\\n logger.warn('No config found!')\\n return\\n}\\n\\nconst apiKey = config.openai?.key || process.env.OPENAI_API_KEY\\n```\\n\\n### Zod Schemas and Types\\n\\n```typescript\\nimport { z } from 'zod'\\nimport { toYargs } from '@plastichub/osr-commons'\\n\\n// Define schema\\nconst MySchema = z.object({\\n field: z.string().describe('Description')\\n})\\n\\n// Convert to Yargs options\\nconst options = (yargs: Argv) => toYargs(yargs, MySchema)\\n\\n// Generate types\\nllm-tools types\\n```\\n\\n## Development\\n\\n```bash\\n# Clone repository\\ngit clone \\ncd llm-tools-cli\\n\\n# Install dependencies\\npnpm install\\n\\n# Build\\npnpm build\\n\\n# Run development version\\npnpm dev\\n\\n# Generate types\\npnpm types\\n```\\n\\n## Project Structure\\n\\n```\\nsrc/\\n├── index.ts # Logger setup\\n├── main.ts # CLI entry\\n├── constants.ts # Constants\\n├── tools.ts # Tool registry\\n├── zod_schemas.ts # Zod schemas\\n├── zod_types.ts # Generated types\\n├── commands/\\n│ ├── index.ts # Command registration\\n│ ├── list.ts # List command\\n│ ├── invoke.ts # Invoke command\\n│ └── types.ts # Types command\\n└── lib/\\n └── tools/\\n ├── fs.ts # Filesystem tools\\n ├── git.ts # Git tools\\n └── npm.ts # NPM tools\\n```\\n\"\n },\n {\n \"path\": \"src\\\\zod_types.ts\",\n \"content\": \"export interface IOptions {\\n /** Directory path to list files from */\\n directory: string;\\n /** Glob pattern for filtering files */\\n pattern?: string | undefined;\\n}\\nexport interface IOptions {\\n /** Path of the file to remove */\\n path: string;\\n}\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\n/** Schema for listing files in a directory */\\nexport const FileListingOptionsSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n});\\n\\n/** Schema for file removal operations */\\nexport const FileRemovalOptionsSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n});\\n\\n/** Schema for git commit operations */\\nexport const GitCommitSchema = z.object({\\n files: z.array(z.string()).describe('Files to commit'),\\n message: z.string().describe('Commit message')\\n});\\n\\n/** Schema for git revert operations */\\nexport const GitRevertSchema = z.object({\\n files: z.array(z.string()).describe('Files to revert')\\n});\\n\\n/** Schema for git version switch operations */\\nexport const GitSwitchVersionSchema = z.object({\\n branch: z.string().describe('Branch name to switch to'),\\n remote: z.string().default('origin').describe('Remote name')\\n});\\n\\n/** Schema for git raw file retrieval */\\nexport const GitRawFileSchema = z.object({\\n url: z.string().optional().describe('Full GitHub raw URL'),\\n repo: z.string().optional().describe('Repository in format owner/repo'),\\n path: z.string().optional().describe('File path within repository')\\n}).refine(\\n data => (data.url) || (data.repo && data.path),\\n 'Either url or both repo and path must be provided'\\n);\\n\\n/** Schema for npm run command */\\nexport const NpmRunSchema = z.object({\\n command: z.string().describe('Command to run (e.g. install, test, etc)'),\\n args: z.array(z.string()).optional().describe('Additional arguments for the command')\\n});\\n\\n/** Schema for tool invocation parameters */\\nexport const InvokeToolSchema = z.object({\\n tools: z.string().describe('Tool category to use (fs, npm, git)'),\\n function: z.string().describe('Function name to invoke'),\\n target: z.string().default(process.cwd()).describe('Target directory'),\\n params: z.string().optional().describe('JSON string of parameters'),\\n output: z.string().optional().describe('Path to write the output to'),\\n env_key: z.string().optional().describe('Environment configuration key')\\n});\\n\\n/** Schema for list command options */\\nexport const ListCommandSchema = z.object({\\n output: z.string().default(\\\"./llm-tools.json\\\").describe('Output file path for tools list')\\n});\\n\\n/** Schema for tool listing options */\\nexport const ToolListingOptionsSchema = z.object({\\n output: z.string().default('./llm-tools.json').describe('Output file path for tools list')\\n});\"\n },\n {\n \"path\": \"src\\\\tools.ts\",\n \"content\": \"import { tools as fsTools } from './lib/tools/fs';\\nimport { tools as npmTools } from './lib/tools/npm';\\nimport { tools as gitTools } from './lib/tools/git';\\n\\nexport const tools = {\\n fs: fsTools,\\n npm: npmTools,\\n git: gitTools\\n};\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport yargs from 'yargs';\\nimport { commands } from './commands';\\nimport { logger } from './';\\n\\nasync function main() {\\n try {\\n const argv = await commands(yargs).argv;\\n } catch (error) {\\n logger.error('Error executing command:', error);\\n process.exit(1);\\n }\\n}\\n\\nmain();\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\npm.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'build_project',\\n description: 'Build project using pnpm build command',\\n parameters: {\\n type: 'object',\\n properties: {},\\n required: []\\n },\\n function: async () => {\\n try {\\n logger.debug(`Tool::BuildProject Building project at ${target}`);\\n const { stdout, stderr } = await execAsync('pnpm build', {\\n cwd: target\\n });\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error : any) {\\n logger.error('Error building project', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'run_npm',\\n description: 'Run an npm/pnpm command',\\n parameters: {\\n type: 'object',\\n properties: {\\n command: { type: 'string', description: 'Command to run (e.g. install, test, etc)' },\\n args: { \\n type: 'array',\\n items: { type: 'string' },\\n description: 'Additional arguments for the command',\\n optional: true\\n }\\n },\\n required: ['command']\\n },\\n function: async (params: any) => {\\n try {\\n const args = params.args ? params.args.join(' ') : '';\\n const fullCommand = `pnpm ${params.command} ${args}`.trim();\\n logger.debug(`Tool::RunNpm Running command: ${fullCommand}`);\\n const { stdout, stderr } = await execAsync(fullCommand, {\\n cwd: target\\n });\\n\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error: any) {\\n logger.error('Error running npm command', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\git.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport simpleGit, { SimpleGit } from 'simple-git';\\nimport axios from 'axios';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n const git: SimpleGit = simpleGit(target);\\n\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'commit_files',\\n description: 'Commit files to git repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n files: {\\n type: 'array',\\n items: { type: 'string' }\\n },\\n message: { type: 'string' }\\n },\\n required: ['files', 'message']\\n },\\n function: async (params: any) => {\\n try {\\n logger.debug(`Tool::Git Committing files with message: ${params.message}`);\\n await git.add(params.files);\\n const result = await git.commit(params.message);\\n return {\\n success: true,\\n output: result,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error committing files', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'revert_files',\\n description: 'Revert specified files in git repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n files: {\\n type: 'array',\\n items: { type: 'string' }\\n }\\n },\\n required: ['files']\\n },\\n function: async (params: any) => {\\n try {\\n logger.debug(`Tool::Git Reverting files: ${params.files.join(', ')}`);\\n await git.checkout(['--', ...params.files]);\\n return {\\n success: true,\\n output: 'Files reverted successfully',\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error reverting files', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'switch_version',\\n description: 'Switch to previous version from remote',\\n parameters: {\\n type: 'object',\\n properties: {\\n branch: { type: 'string' },\\n remote: { \\n type: 'string',\\n default: 'origin'\\n }\\n },\\n required: ['branch']\\n },\\n function: async (params: any) => {\\n try {\\n const remote = params.remote || 'origin';\\n logger.debug(`Tool::Git Switching to branch ${params.branch} from ${remote}`);\\n const result = await git.checkout(`${remote}/${params.branch}`);\\n return {\\n success: true,\\n output: result,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error switching version', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'get_raw_file',\\n description: 'Retrieve raw content of a file from GitHub repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n url: { \\n type: 'string',\\n description: 'Full GitHub raw URL or repository path'\\n },\\n repo: {\\n type: 'string',\\n description: 'Repository in format owner/repo'\\n },\\n path: {\\n type: 'string',\\n description: 'File path within repository'\\n }\\n },\\n oneOf: [\\n { required: ['url'] },\\n { required: ['repo', 'path'] }\\n ]\\n },\\n function: async (params: any) => {\\n try {\\n let fileUrl = params.url;\\n if (!fileUrl && params.repo && params.path) {\\n fileUrl = `https://raw.githubusercontent.com/${params.repo}/main/${params.path}`;\\n }\\n \\n logger.debug(`Tool::Git Fetching raw file from ${fileUrl}`);\\n const response = await axios.get(fileUrl);\\n return {\\n success: true,\\n content: response.data,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error fetching raw file', error);\\n return {\\n success: false,\\n content: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { \\n FileListingOptionsSchema, \\n FileRemovalOptionsSchema,\\n GitCommitSchema,\\n GitRevertSchema,\\n GitSwitchVersionSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema \\n} from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n FileListingOptionsSchema,\\n FileRemovalOptionsSchema,\\n GitCommitSchema,\\n GitRevertSchema,\\n GitSwitchVersionSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema\\n ], 'src/zod_types.ts');\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\list.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { ListCommandSchema } from '../zod_schemas';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport type { Argv } from 'yargs';\\n\\nexport const options = (yargs: Argv) => toYargs(yargs, ListCommandSchema);\\n\\nexport const list = async (argv: any) => {\\n // Initialize tools with current directory\\n const fsTools = tools.fs(process.cwd());\\n const npmTools = tools.npm(process.cwd());\\n const gitTools = tools.git(process.cwd());\\n\\n const toolsList = {\\n fs: fsTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'fs'\\n })),\\n npm: npmTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'npm'\\n })),\\n git: gitTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'git'\\n }))\\n };\\n\\n logger.info('Available Tools:\\\\n');\\n \\n logger.info('Filesystem Tools:');\\n fsTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nNPM Tools:');\\n npmTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nGit Tools:');\\n gitTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n if (argv.output) {\\n logger.info(`\\\\nWriting tools list to ${argv.output}`);\\n write(argv.output, JSON.stringify(toolsList, null, 2));\\n }\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\invoke.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { InvokeToolSchema } from '../zod_schemas';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport type { Argv } from 'yargs';\\nimport * as path from 'path';\\n\\nconst options = (yargs: Argv) => toYargs(yargs, InvokeToolSchema);\\n\\nexport const invoke = async (argv: any) => {\\n try {\\n const { tools: toolCategory, function: funcName, target, params, output } = argv;\\n \\n // Get tool category\\n const toolSet = tools[toolCategory];\\n if (!toolSet) {\\n logger.error(`Tool category '${toolCategory}' not found`);\\n return;\\n }\\n\\n // Initialize tools with target directory\\n const toolList = toolSet(target);\\n \\n // Find specific function\\n const tool = toolList.find(t => t.function.name === funcName);\\n if (!tool) {\\n logger.error(`Function '${funcName}' not found in ${toolCategory} tools`);\\n return;\\n }\\n\\n // Parse parameters if provided\\n const parameters = params ? JSON.parse(params) : {};\\n \\n // Execute tool function\\n logger.info(`Invoking ${toolCategory}::${funcName}`);\\n const result = await tool.function.function(parameters);\\n \\n // Handle output\\n if (output) {\\n const outputPath = path.isAbsolute(output) ? output : path.join(process.cwd(), output);\\n logger.info(`Writing output to ${outputPath}`);\\n write(outputPath, JSON.stringify(result, null, 2));\\n } else {\\n logger.info('Result:', result);\\n }\\n \\n return result;\\n } catch (error) {\\n logger.error('Error invoking tool:', error);\\n throw error;\\n }\\n};\\n\\nexport { options as invokeOptions };\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\nimport { list, options as listOptions } from './list';\\nimport { invoke, invokeOptions } from './invoke';\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons';\\nimport { logger } from '../';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .command('list', 'List all available tools and their descriptions', listOptions, list)\\n .command('invoke', 'Invoke a specific tool function', invokeOptions, invoke)\\n .option('env_key', {\\n type: 'string',\\n description: 'Environment configuration key'\\n })\\n .middleware([(argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any;\\n if (!config) {\\n logger.warn('No config found!');\\n return;\\n }\\n return config;\\n }])\\n .strict()\\n .help();\\n};\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T13:25:41.269Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n### LLM Tools\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { resolve } from \"@plastichub/osr-commons\"\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any, variables:Record={}): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = path.resolve(resolve(join(target, file.path),false,variables))\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : Add another tool in tools/terminal : execute command (cmd, args), capture all output\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\",\\n \\\"list\\\": \\\"ts-node src/main.ts list\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"simple-git\\\": \\\"^3.22.0\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nA command-line interface and library for Language Model tools with filesystem, npm, git, and terminal operations support.\\n\\n## Prerequisites\\n\\n- Node.js >= 16\\n- pnpm (recommended) or npm\\n- Git (for git operations)\\n\\n## Installation\\n\\n```bash\\n# Install globally\\npnpm add -g llm-tools-cli\\n\\n# Or install in project\\npnpm add llm-tools-cli\\n```\\n\\n## Quick Start\\n\\n```bash\\n# Generate TypeScript types\\nllm-tools types\\n\\n# List available tools\\nllm-tools list\\n\\n# Invoke a tool\\nllm-tools invoke --tools=fs --function=list_files --directory=src\\n```\\n\\n## Configuration\\n\\nCreate a configuration file or use environment variables:\\n\\n```json\\n{\\n \\\"openai\\\": {\\n \\\"key\\\": \\\"your-api-key\\\"\\n }\\n}\\n```\\n\\nOr use environment variable:\\n```bash\\nexport OPENAI_API_KEY=your-api-key\\n```\\n\\n## Available Commands\\n\\n### Generate TypeScript Types\\n\\n```bash\\nllm-tools types\\n```\\n\\nGenerates TypeScript interfaces from all Zod schemas in the project.\\n\\n### List Available Tools\\n\\n```bash\\nllm-tools list [options]\\n\\nOptions:\\n --output Output file path [default: \\\"./llm-tools.json\\\"]\\n```\\n\\nLists all available tools and their descriptions.\\n\\n### Invoke Tool\\n\\n```bash\\nllm-tools invoke [options]\\n\\nOptions:\\n --tools Tool category (fs, npm, git, terminal)\\n --function Function name to invoke\\n --target Target directory [default: current]\\n --params JSON string of parameters\\n --output Output file path\\n --env_key Environment key\\n```\\n\\n## Tool Categories and Functions\\n\\n### Filesystem Tools\\n\\n```typescript\\n// List files\\nllm-tools invoke --tools=fs --function=list_files \\\\\\n --params='{\\\"directory\\\":\\\"src\\\",\\\"pattern\\\":\\\"**/*.ts\\\"}'\\n\\n// Remove file\\nllm-tools invoke --tools=fs --function=remove_file \\\\\\n --params='{\\\"path\\\":\\\"temp.txt\\\"}'\\n```\\n\\n### Git Tools\\n\\n```typescript\\n// Commit files\\nllm-tools invoke --tools=git --function=commit_files \\\\\\n --params='{\\\"files\\\":[\\\"src/main.ts\\\"],\\\"message\\\":\\\"Update code\\\"}'\\n\\n// Revert files\\nllm-tools invoke --tools=git --function=revert_files \\\\\\n --params='{\\\"files\\\":[\\\"src/config.ts\\\"]}'\\n\\n// Switch version\\nllm-tools invoke --tools=git --function=switch_version \\\\\\n --params='{\\\"branch\\\":\\\"main\\\",\\\"remote\\\":\\\"origin\\\"}'\\n\\n// Get raw file from GitHub\\nllm-tools invoke --tools=git --function=get_raw_file \\\\\\n --params='{\\\"repo\\\":\\\"owner/repo\\\",\\\"path\\\":\\\"file.ts\\\"}'\\n```\\n\\n### NPM Tools\\n\\n```typescript\\n// Build project\\nllm-tools invoke --tools=npm --function=build_project\\n\\n// Run npm command\\nllm-tools invoke --tools=npm --function=run_npm \\\\\\n --params='{\\\"command\\\":\\\"install\\\",\\\"args\\\":[\\\"--save-dev\\\",\\\"typescript\\\"]}'\\n```\\n\\n### Terminal Tools\\n\\n```typescript\\n// Execute command\\nllm-tools invoke --tools=terminal --function=execute_command \\\\\\n --params='{\\\"command\\\":\\\"ls\\\",\\\"args\\\":[\\\"-la\\\"],\\\"cwd\\\":\\\"src\\\"}'\\n```\\n\\n## Library Usage\\n\\n### Filesystem Operations\\n\\n```typescript\\nimport { sync as rm } from '@plastichub/fs/remove'\\nimport { sync as dir } from '@plastichub/fs/dir'\\nimport { sync as write } from '@plastichub/fs/write'\\nimport { sync as read } from '@plastichub/fs/read'\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob'\\n\\n// Create directory\\ndir('path/to/dir')\\n\\n// Write file\\nwrite('file.txt', 'content')\\n\\n// Read file\\nconst content = read('file.txt')\\n\\n// Remove file/directory\\nrm('path/to/remove')\\n\\n// Find files\\nconst files = glob('src', ['**/*.ts'])\\n```\\n\\n### Git Operations\\n\\n```typescript\\nimport { tools as gitTools } from './lib/tools/git'\\n\\nconst git = gitTools(process.cwd())\\n\\n// Commit files\\nawait git.find(t => t.function.name === 'commit_files')\\n .function.function({\\n files: ['src/main.ts'],\\n message: 'Update code'\\n })\\n\\n// Revert files\\nawait git.find(t => t.function.name === 'revert_files')\\n .function.function({\\n files: ['src/config.ts']\\n })\\n\\n// Switch version\\nawait git.find(t => t.function.name === 'switch_version')\\n .function.function({\\n branch: 'main',\\n remote: 'origin'\\n })\\n```\\n\\n### Terminal Operations\\n\\n```typescript\\nimport { tools as terminalTools } from './lib/tools/terminal'\\n\\nconst terminal = terminalTools(process.cwd())\\n\\n// Execute command\\nawait terminal.find(t => t.function.name === 'execute_command')\\n .function.function({\\n command: 'ls',\\n args: ['-la'],\\n cwd: 'src'\\n })\\n```\\n\\n### Logging\\n\\n```typescript\\nimport { Logger } from 'tslog'\\nimport { createLogger } from '@plastichub/osr-log'\\n\\nexport const logger: Logger = createLogger('package-name')\\n\\nlogger.info('Info message')\\nlogger.warn('Warning message')\\nlogger.error('Error message')\\n```\\n\\n### Configuration\\n\\n```typescript\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\\n\\nconst config = CONFIG_DEFAULT('env_key')\\nif (!config) {\\n logger.warn('No config found!')\\n return\\n}\\n\\nconst apiKey = config.openai?.key || process.env.OPENAI_API_KEY\\n```\\n\\n### Zod Schemas and Types\\n\\n```typescript\\nimport { z } from 'zod'\\nimport { toYargs } from '@plastichub/osr-commons'\\n\\n// Define schema\\nconst MySchema = z.object({\\n field: z.string().describe('Description')\\n})\\n\\n// Convert to Yargs options\\nconst options = (yargs: Argv) => toYargs(yargs, MySchema)\\n\\n// Generate types\\nllm-tools types\\n```\\n\\n## Development\\n\\n```bash\\n# Clone repository\\ngit clone \\ncd llm-tools-cli\\n\\n# Install dependencies\\npnpm install\\n\\n# Build\\npnpm build\\n\\n# Run development version\\npnpm dev\\n\\n# Generate types\\npnpm types\\n```\\n\\n## Project Structure\\n\\n```\\nsrc/\\n├── index.ts # Logger setup\\n├── main.ts # CLI entry\\n├── constants.ts # Constants\\n├── tools.ts # Tool registry\\n├── zod_schemas.ts # Zod schemas\\n├── zod_types.ts # Generated types\\n├── commands/\\n│ ├── index.ts # Command registration\\n│ ├── list.ts # List command\\n│ ├── invoke.ts # Invoke command\\n│ └── types.ts # Types command\\n└── lib/\\n └── tools/\\n ├── fs.ts # Filesystem tools\\n ├── git.ts # Git tools\\n ├── npm.ts # NPM tools\\n └── terminal.ts # Terminal tools\\n```\"\n },\n {\n \"path\": \"src\\\\zod_types.ts\",\n \"content\": \"export interface IOptions {\\n /** Directory path to list files from */\\n directory: string;\\n /** Glob pattern for filtering files */\\n pattern?: string | undefined;\\n}\\nexport interface IOptions {\\n /** Path of the file to remove */\\n path: string;\\n}\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\n/** Schema for listing files in a directory */\\nexport const FileListingOptionsSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n});\\n\\n/** Schema for file removal operations */\\nexport const FileRemovalOptionsSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n});\\n\\n/** Schema for git commit operations */\\nexport const GitCommitSchema = z.object({\\n files: z.array(z.string()).describe('Files to commit'),\\n message: z.string().describe('Commit message')\\n});\\n\\n/** Schema for git revert operations */\\nexport const GitRevertSchema = z.object({\\n files: z.array(z.string()).describe('Files to revert')\\n});\\n\\n/** Schema for git version switch operations */\\nexport const GitSwitchVersionSchema = z.object({\\n branch: z.string().describe('Branch name to switch to'),\\n remote: z.string().default('origin').describe('Remote name')\\n});\\n\\n/** Schema for git raw file retrieval */\\nexport const GitRawFileSchema = z.object({\\n url: z.string().optional().describe('Full GitHub raw URL'),\\n repo: z.string().optional().describe('Repository in format owner/repo'),\\n path: z.string().optional().describe('File path within repository')\\n}).refine(\\n data => (data.url) || (data.repo && data.path),\\n 'Either url or both repo and path must be provided'\\n);\\n\\n/** Schema for npm run command */\\nexport const NpmRunSchema = z.object({\\n command: z.string().describe('Command to run (e.g. install, test, etc)'),\\n args: z.array(z.string()).optional().describe('Additional arguments for the command')\\n});\\n\\n/** Schema for terminal command execution */\\nexport const TerminalCommandSchema = z.object({\\n command: z.string().describe('Command to execute'),\\n args: z.array(z.string()).optional().describe('Command arguments'),\\n cwd: z.string().optional().describe('Working directory for command execution')\\n});\\n\\n/** Schema for tool invocation parameters */\\nexport const InvokeToolSchema = z.object({\\n tools: z.string().describe('Tool category to use (fs, npm, git, terminal)'),\\n function: z.string().describe('Function name to invoke'),\\n target: z.string().default(process.cwd()).describe('Target directory'),\\n params: z.string().optional().describe('JSON string of parameters'),\\n output: z.string().optional().describe('Path to write the output to'),\\n env_key: z.string().optional().describe('Environment configuration key')\\n});\\n\\n/** Schema for list command options */\\nexport const ListCommandSchema = z.object({\\n output: z.string().default(\\\"./llm-tools.json\\\").describe('Output file path for tools list')\\n});\\n\\n/** Schema for tool listing options */\\nexport const ToolListingOptionsSchema = z.object({\\n output: z.string().default('./llm-tools.json').describe('Output file path for tools list')\\n});\"\n },\n {\n \"path\": \"src\\\\tools.ts\",\n \"content\": \"import { tools as fsTools } from './lib/tools/fs';\\nimport { tools as npmTools } from './lib/tools/npm';\\nimport { tools as gitTools } from './lib/tools/git';\\nimport { tools as terminalTools } from './lib/tools/terminal';\\n\\nexport const tools = {\\n fs: fsTools,\\n npm: npmTools,\\n git: gitTools,\\n terminal: terminalTools\\n};\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport yargs from 'yargs';\\nimport { commands } from './commands';\\nimport { logger } from './';\\n\\nasync function main() {\\n try {\\n const argv = await commands(yargs).argv;\\n } catch (error) {\\n logger.error('Error executing command:', error);\\n process.exit(1);\\n }\\n}\\n\\nmain();\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\npm.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'build_project',\\n description: 'Build project using pnpm build command',\\n parameters: {\\n type: 'object',\\n properties: {},\\n required: []\\n },\\n function: async () => {\\n try {\\n logger.debug(`Tool::BuildProject Building project at ${target}`);\\n const { stdout, stderr } = await execAsync('pnpm build', {\\n cwd: target\\n });\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error : any) {\\n logger.error('Error building project', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'run_npm',\\n description: 'Run an npm/pnpm command',\\n parameters: {\\n type: 'object',\\n properties: {\\n command: { type: 'string', description: 'Command to run (e.g. install, test, etc)' },\\n args: { \\n type: 'array',\\n items: { type: 'string' },\\n description: 'Additional arguments for the command',\\n optional: true\\n }\\n },\\n required: ['command']\\n },\\n function: async (params: any) => {\\n try {\\n const args = params.args ? params.args.join(' ') : '';\\n const fullCommand = `pnpm ${params.command} ${args}`.trim();\\n logger.debug(`Tool::RunNpm Running command: ${fullCommand}`);\\n const { stdout, stderr } = await execAsync(fullCommand, {\\n cwd: target\\n });\\n\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error: any) {\\n logger.error('Error running npm command', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\git.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport simpleGit, { SimpleGit } from 'simple-git';\\nimport axios from 'axios';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n const git: SimpleGit = simpleGit(target);\\n\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'commit_files',\\n description: 'Commit files to git repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n files: {\\n type: 'array',\\n items: { type: 'string' }\\n },\\n message: { type: 'string' }\\n },\\n required: ['files', 'message']\\n },\\n function: async (params: any) => {\\n try {\\n logger.debug(`Tool::Git Committing files with message: ${params.message}`);\\n await git.add(params.files);\\n const result = await git.commit(params.message);\\n return {\\n success: true,\\n output: result,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error committing files', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'revert_files',\\n description: 'Revert specified files in git repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n files: {\\n type: 'array',\\n items: { type: 'string' }\\n }\\n },\\n required: ['files']\\n },\\n function: async (params: any) => {\\n try {\\n logger.debug(`Tool::Git Reverting files: ${params.files.join(', ')}`);\\n await git.checkout(['--', ...params.files]);\\n return {\\n success: true,\\n output: 'Files reverted successfully',\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error reverting files', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'switch_version',\\n description: 'Switch to previous version from remote',\\n parameters: {\\n type: 'object',\\n properties: {\\n branch: { type: 'string' },\\n remote: { \\n type: 'string',\\n default: 'origin'\\n }\\n },\\n required: ['branch']\\n },\\n function: async (params: any) => {\\n try {\\n const remote = params.remote || 'origin';\\n logger.debug(`Tool::Git Switching to branch ${params.branch} from ${remote}`);\\n const result = await git.checkout(`${remote}/${params.branch}`);\\n return {\\n success: true,\\n output: result,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error switching version', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'get_raw_file',\\n description: 'Retrieve raw content of a file from GitHub repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n url: { \\n type: 'string',\\n description: 'Full GitHub raw URL or repository path'\\n },\\n repo: {\\n type: 'string',\\n description: 'Repository in format owner/repo'\\n },\\n path: {\\n type: 'string',\\n description: 'File path within repository'\\n }\\n },\\n oneOf: [\\n { required: ['url'] },\\n { required: ['repo', 'path'] }\\n ]\\n },\\n function: async (params: any) => {\\n try {\\n let fileUrl = params.url;\\n if (!fileUrl && params.repo && params.path) {\\n fileUrl = `https://raw.githubusercontent.com/${params.repo}/main/${params.path}`;\\n }\\n \\n logger.debug(`Tool::Git Fetching raw file from ${fileUrl}`);\\n const response = await axios.get(fileUrl);\\n return {\\n success: true,\\n content: response.data,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error fetching raw file', error);\\n return {\\n success: false,\\n content: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { \\n FileListingOptionsSchema, \\n FileRemovalOptionsSchema,\\n GitCommitSchema,\\n GitRevertSchema,\\n GitSwitchVersionSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema,\\n TerminalCommandSchema \\n} from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n FileListingOptionsSchema,\\n FileRemovalOptionsSchema,\\n GitCommitSchema,\\n GitRevertSchema,\\n GitSwitchVersionSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema,\\n TerminalCommandSchema\\n ], 'src/zod_types.ts');\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\list.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { ListCommandSchema } from '../zod_schemas';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport type { Argv } from 'yargs';\\n\\nexport const options = (yargs: Argv) => toYargs(yargs, ListCommandSchema);\\n\\nexport const list = async (argv: any) => {\\n // Initialize tools with current directory\\n const fsTools = tools.fs(process.cwd());\\n const npmTools = tools.npm(process.cwd());\\n const gitTools = tools.git(process.cwd());\\n\\n const toolsList = {\\n fs: fsTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'fs'\\n })),\\n npm: npmTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'npm'\\n })),\\n git: gitTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'git'\\n }))\\n };\\n\\n logger.info('Available Tools:\\\\n');\\n \\n logger.info('Filesystem Tools:');\\n fsTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nNPM Tools:');\\n npmTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nGit Tools:');\\n gitTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n if (argv.output) {\\n logger.info(`\\\\nWriting tools list to ${argv.output}`);\\n write(argv.output, JSON.stringify(toolsList, null, 2));\\n }\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\invoke.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { InvokeToolSchema } from '../zod_schemas';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport type { Argv } from 'yargs';\\nimport * as path from 'path';\\n\\nconst options = (yargs: Argv) => toYargs(yargs, InvokeToolSchema);\\n\\nexport const invoke = async (argv: any) => {\\n try {\\n const { tools: toolCategory, function: funcName, target, params, output } = argv;\\n \\n // Get tool category\\n const toolSet = tools[toolCategory];\\n if (!toolSet) {\\n logger.error(`Tool category '${toolCategory}' not found`);\\n return;\\n }\\n\\n // Initialize tools with target directory\\n const toolList = toolSet(target);\\n \\n // Find specific function\\n const tool = toolList.find(t => t.function.name === funcName);\\n if (!tool) {\\n logger.error(`Function '${funcName}' not found in ${toolCategory} tools`);\\n return;\\n }\\n\\n // Parse parameters if provided\\n const parameters = params ? JSON.parse(params) : {};\\n \\n // Execute tool function\\n logger.info(`Invoking ${toolCategory}::${funcName}`);\\n const result = await tool.function.function(parameters);\\n \\n // Handle output\\n if (output) {\\n const outputPath = path.isAbsolute(output) ? output : path.join(process.cwd(), output);\\n logger.info(`Writing output to ${outputPath}`);\\n write(outputPath, JSON.stringify(result, null, 2));\\n } else {\\n logger.info('Result:', result);\\n }\\n \\n return result;\\n } catch (error) {\\n logger.error('Error invoking tool:', error);\\n throw error;\\n }\\n};\\n\\nexport { options as invokeOptions };\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\nimport { list, options as listOptions } from './list';\\nimport { invoke, invokeOptions } from './invoke';\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons';\\nimport { logger } from '../';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .command('list', 'List all available tools and their descriptions', listOptions, list)\\n .command('invoke', 'Invoke a specific tool function', invokeOptions, invoke)\\n .option('env_key', {\\n type: 'string',\\n description: 'Environment configuration key'\\n })\\n .middleware([(argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any;\\n if (!config) {\\n logger.warn('No config found!');\\n return;\\n }\\n return config;\\n }])\\n .strict()\\n .help();\\n};\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T13:27:18.857Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n### LLM Tools\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { resolve } from \"@plastichub/osr-commons\"\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any, variables:Record={}): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = path.resolve(resolve(join(target, file.path),false,variables))\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : Add support for background tasks in execute_command tool\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\",\\n \\\"list\\\": \\\"ts-node src/main.ts list\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"simple-git\\\": \\\"^3.22.0\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nA command-line interface and library for Language Model tools with filesystem, npm, git, and terminal operations support.\\n\\n## Prerequisites\\n\\n- Node.js >= 16\\n- pnpm (recommended) or npm\\n- Git (for git operations)\\n\\n## Installation\\n\\n```bash\\n# Install globally\\npnpm add -g llm-tools-cli\\n\\n# Or install in project\\npnpm add llm-tools-cli\\n```\\n\\n## Quick Start\\n\\n```bash\\n# Generate TypeScript types\\nllm-tools types\\n\\n# List available tools\\nllm-tools list\\n\\n# Invoke a tool\\nllm-tools invoke --tools=fs --function=list_files --directory=src\\n```\\n\\n## Configuration\\n\\nCreate a configuration file or use environment variables:\\n\\n```json\\n{\\n \\\"openai\\\": {\\n \\\"key\\\": \\\"your-api-key\\\"\\n }\\n}\\n```\\n\\nOr use environment variable:\\n```bash\\nexport OPENAI_API_KEY=your-api-key\\n```\\n\\n## Available Commands\\n\\n### Generate TypeScript Types\\n\\n```bash\\nllm-tools types\\n```\\n\\nGenerates TypeScript interfaces from all Zod schemas in the project.\\n\\n### List Available Tools\\n\\n```bash\\nllm-tools list [options]\\n\\nOptions:\\n --output Output file path [default: \\\"./llm-tools.json\\\"]\\n```\\n\\nLists all available tools and their descriptions.\\n\\n### Invoke Tool\\n\\n```bash\\nllm-tools invoke [options]\\n\\nOptions:\\n --tools Tool category (fs, npm, git, terminal)\\n --function Function name to invoke\\n --target Target directory [default: current]\\n --params JSON string of parameters\\n --output Output file path\\n --env_key Environment key\\n```\\n\\n## Tool Categories and Functions\\n\\n### Filesystem Tools\\n\\n```typescript\\n// List files\\nllm-tools invoke --tools=fs --function=list_files \\\\\\n --params='{\\\"directory\\\":\\\"src\\\",\\\"pattern\\\":\\\"**/*.ts\\\"}'\\n\\n// Remove file\\nllm-tools invoke --tools=fs --function=remove_file \\\\\\n --params='{\\\"path\\\":\\\"temp.txt\\\"}'\\n```\\n\\n### Git Tools\\n\\n```typescript\\n// Commit files\\nllm-tools invoke --tools=git --function=commit_files \\\\\\n --params='{\\\"files\\\":[\\\"src/main.ts\\\"],\\\"message\\\":\\\"Update code\\\"}'\\n\\n// Revert files\\nllm-tools invoke --tools=git --function=revert_files \\\\\\n --params='{\\\"files\\\":[\\\"src/config.ts\\\"]}'\\n\\n// Switch version\\nllm-tools invoke --tools=git --function=switch_version \\\\\\n --params='{\\\"branch\\\":\\\"main\\\",\\\"remote\\\":\\\"origin\\\"}'\\n\\n// Get raw file from GitHub\\nllm-tools invoke --tools=git --function=get_raw_file \\\\\\n --params='{\\\"repo\\\":\\\"owner/repo\\\",\\\"path\\\":\\\"file.ts\\\"}'\\n```\\n\\n### NPM Tools\\n\\n```typescript\\n// Build project\\nllm-tools invoke --tools=npm --function=build_project\\n\\n// Run npm command\\nllm-tools invoke --tools=npm --function=run_npm \\\\\\n --params='{\\\"command\\\":\\\"install\\\",\\\"args\\\":[\\\"--save-dev\\\",\\\"typescript\\\"]}'\\n```\\n\\n### Terminal Tools\\n\\n```typescript\\n// Execute command\\nllm-tools invoke --tools=terminal --function=execute_command \\\\\\n --params='{\\\"command\\\":\\\"ls\\\",\\\"args\\\":[\\\"-la\\\"],\\\"cwd\\\":\\\"src\\\"}'\\n```\\n\\n## Library Usage\\n\\n### Filesystem Operations\\n\\n```typescript\\nimport { sync as rm } from '@plastichub/fs/remove'\\nimport { sync as dir } from '@plastichub/fs/dir'\\nimport { sync as write } from '@plastichub/fs/write'\\nimport { sync as read } from '@plastichub/fs/read'\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob'\\n\\n// Create directory\\ndir('path/to/dir')\\n\\n// Write file\\nwrite('file.txt', 'content')\\n\\n// Read file\\nconst content = read('file.txt')\\n\\n// Remove file/directory\\nrm('path/to/remove')\\n\\n// Find files\\nconst files = glob('src', ['**/*.ts'])\\n```\\n\\n### Git Operations\\n\\n```typescript\\nimport { tools as gitTools } from './lib/tools/git'\\n\\nconst git = gitTools(process.cwd())\\n\\n// Commit files\\nawait git.find(t => t.function.name === 'commit_files')\\n .function.function({\\n files: ['src/main.ts'],\\n message: 'Update code'\\n })\\n\\n// Revert files\\nawait git.find(t => t.function.name === 'revert_files')\\n .function.function({\\n files: ['src/config.ts']\\n })\\n\\n// Switch version\\nawait git.find(t => t.function.name === 'switch_version')\\n .function.function({\\n branch: 'main',\\n remote: 'origin'\\n })\\n```\\n\\n### Terminal Operations\\n\\n```typescript\\nimport { tools as terminalTools } from './lib/tools/terminal'\\n\\nconst terminal = terminalTools(process.cwd())\\n\\n// Execute command\\nawait terminal.find(t => t.function.name === 'execute_command')\\n .function.function({\\n command: 'ls',\\n args: ['-la'],\\n cwd: 'src'\\n })\\n```\\n\\n### Logging\\n\\n```typescript\\nimport { Logger } from 'tslog'\\nimport { createLogger } from '@plastichub/osr-log'\\n\\nexport const logger: Logger = createLogger('package-name')\\n\\nlogger.info('Info message')\\nlogger.warn('Warning message')\\nlogger.error('Error message')\\n```\\n\\n### Configuration\\n\\n```typescript\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\\n\\nconst config = CONFIG_DEFAULT('env_key')\\nif (!config) {\\n logger.warn('No config found!')\\n return\\n}\\n\\nconst apiKey = config.openai?.key || process.env.OPENAI_API_KEY\\n```\\n\\n### Zod Schemas and Types\\n\\n```typescript\\nimport { z } from 'zod'\\nimport { toYargs } from '@plastichub/osr-commons'\\n\\n// Define schema\\nconst MySchema = z.object({\\n field: z.string().describe('Description')\\n})\\n\\n// Convert to Yargs options\\nconst options = (yargs: Argv) => toYargs(yargs, MySchema)\\n\\n// Generate types\\nllm-tools types\\n```\\n\\n## Development\\n\\n```bash\\n# Clone repository\\ngit clone \\ncd llm-tools-cli\\n\\n# Install dependencies\\npnpm install\\n\\n# Build\\npnpm build\\n\\n# Run development version\\npnpm dev\\n\\n# Generate types\\npnpm types\\n```\\n\\n## Project Structure\\n\\n```\\nsrc/\\n├── index.ts # Logger setup\\n├── main.ts # CLI entry\\n├── constants.ts # Constants\\n├── tools.ts # Tool registry\\n├── zod_schemas.ts # Zod schemas\\n├── zod_types.ts # Generated types\\n├── commands/\\n│ ├── index.ts # Command registration\\n│ ├── list.ts # List command\\n│ ├── invoke.ts # Invoke command\\n│ └── types.ts # Types command\\n└── lib/\\n └── tools/\\n ├── fs.ts # Filesystem tools\\n ├── git.ts # Git tools\\n ├── npm.ts # NPM tools\\n └── terminal.ts # Terminal tools\\n```\"\n },\n {\n \"path\": \"src\\\\zod_types.ts\",\n \"content\": \"export interface IOptions {\\n /** Directory path to list files from */\\n directory: string;\\n /** Glob pattern for filtering files */\\n pattern?: string | undefined;\\n}\\nexport interface IOptions {\\n /** Path of the file to remove */\\n path: string;\\n}\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\n/** Schema for listing files in a directory */\\nexport const FileListingOptionsSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n});\\n\\n/** Schema for file removal operations */\\nexport const FileRemovalOptionsSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n});\\n\\n/** Schema for git commit operations */\\nexport const GitCommitSchema = z.object({\\n files: z.array(z.string()).describe('Files to commit'),\\n message: z.string().describe('Commit message')\\n});\\n\\n/** Schema for git revert operations */\\nexport const GitRevertSchema = z.object({\\n files: z.array(z.string()).describe('Files to revert')\\n});\\n\\n/** Schema for git version switch operations */\\nexport const GitSwitchVersionSchema = z.object({\\n branch: z.string().describe('Branch name to switch to'),\\n remote: z.string().default('origin').describe('Remote name')\\n});\\n\\n/** Schema for git raw file retrieval */\\nexport const GitRawFileSchema = z.object({\\n url: z.string().optional().describe('Full GitHub raw URL'),\\n repo: z.string().optional().describe('Repository in format owner/repo'),\\n path: z.string().optional().describe('File path within repository')\\n}).refine(\\n data => (data.url) || (data.repo && data.path),\\n 'Either url or both repo and path must be provided'\\n);\\n\\n/** Schema for npm run command */\\nexport const NpmRunSchema = z.object({\\n command: z.string().describe('Command to run (e.g. install, test, etc)'),\\n args: z.array(z.string()).optional().describe('Additional arguments for the command')\\n});\\n\\n/** Schema for terminal command execution */\\nexport const TerminalCommandSchema = z.object({\\n command: z.string().describe('Command to execute'),\\n args: z.array(z.string()).optional().describe('Command arguments'),\\n cwd: z.string().optional().describe('Working directory for command execution')\\n});\\n\\n/** Schema for tool invocation parameters */\\nexport const InvokeToolSchema = z.object({\\n tools: z.string().describe('Tool category to use (fs, npm, git, terminal)'),\\n function: z.string().describe('Function name to invoke'),\\n target: z.string().default(process.cwd()).describe('Target directory'),\\n params: z.string().optional().describe('JSON string of parameters'),\\n output: z.string().optional().describe('Path to write the output to'),\\n env_key: z.string().optional().describe('Environment configuration key')\\n});\\n\\n/** Schema for list command options */\\nexport const ListCommandSchema = z.object({\\n output: z.string().default(\\\"./llm-tools.json\\\").describe('Output file path for tools list')\\n});\\n\\n/** Schema for tool listing options */\\nexport const ToolListingOptionsSchema = z.object({\\n output: z.string().default('./llm-tools.json').describe('Output file path for tools list')\\n});\"\n },\n {\n \"path\": \"src\\\\tools.ts\",\n \"content\": \"import { tools as fsTools } from './lib/tools/fs';\\nimport { tools as npmTools } from './lib/tools/npm';\\nimport { tools as gitTools } from './lib/tools/git';\\nimport { tools as terminalTools } from './lib/tools/terminal';\\n\\nexport const tools = {\\n fs: fsTools,\\n npm: npmTools,\\n git: gitTools,\\n terminal: terminalTools\\n};\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport yargs from 'yargs';\\nimport { commands } from './commands';\\nimport { logger } from './';\\n\\nasync function main() {\\n try {\\n const argv = await commands(yargs).argv;\\n } catch (error) {\\n logger.error('Error executing command:', error);\\n process.exit(1);\\n }\\n}\\n\\nmain();\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\terminal.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'execute_command',\\n description: 'Execute a terminal command and capture output',\\n parameters: {\\n type: 'object',\\n properties: {\\n command: { \\n type: 'string',\\n description: 'Command to execute'\\n },\\n args: {\\n type: 'array',\\n items: { type: 'string' },\\n description: 'Command arguments',\\n optional: true\\n },\\n cwd: {\\n type: 'string',\\n description: 'Working directory for command execution',\\n optional: true\\n }\\n },\\n required: ['command']\\n },\\n function: async (params: any) => {\\n try {\\n const workingDir = params.cwd ? path.join(target, params.cwd) : target;\\n const args = params.args ? params.args.join(' ') : '';\\n const fullCommand = `${params.command} ${args}`.trim();\\n \\n logger.debug(`Tool::ExecuteCommand Running '${fullCommand}' in ${workingDir}`);\\n const { stdout, stderr } = await execAsync(fullCommand, {\\n cwd: workingDir\\n });\\n\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error: any) {\\n logger.error('Error executing command', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\npm.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'build_project',\\n description: 'Build project using pnpm build command',\\n parameters: {\\n type: 'object',\\n properties: {},\\n required: []\\n },\\n function: async () => {\\n try {\\n logger.debug(`Tool::BuildProject Building project at ${target}`);\\n const { stdout, stderr } = await execAsync('pnpm build', {\\n cwd: target\\n });\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error : any) {\\n logger.error('Error building project', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'run_npm',\\n description: 'Run an npm/pnpm command',\\n parameters: {\\n type: 'object',\\n properties: {\\n command: { type: 'string', description: 'Command to run (e.g. install, test, etc)' },\\n args: { \\n type: 'array',\\n items: { type: 'string' },\\n description: 'Additional arguments for the command',\\n optional: true\\n }\\n },\\n required: ['command']\\n },\\n function: async (params: any) => {\\n try {\\n const args = params.args ? params.args.join(' ') : '';\\n const fullCommand = `pnpm ${params.command} ${args}`.trim();\\n logger.debug(`Tool::RunNpm Running command: ${fullCommand}`);\\n const { stdout, stderr } = await execAsync(fullCommand, {\\n cwd: target\\n });\\n\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error: any) {\\n logger.error('Error running npm command', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\git.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport simpleGit, { SimpleGit } from 'simple-git';\\nimport axios from 'axios';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n const git: SimpleGit = simpleGit(target);\\n\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'commit_files',\\n description: 'Commit files to git repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n files: {\\n type: 'array',\\n items: { type: 'string' }\\n },\\n message: { type: 'string' }\\n },\\n required: ['files', 'message']\\n },\\n function: async (params: any) => {\\n try {\\n logger.debug(`Tool::Git Committing files with message: ${params.message}`);\\n await git.add(params.files);\\n const result = await git.commit(params.message);\\n return {\\n success: true,\\n output: result,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error committing files', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'revert_files',\\n description: 'Revert specified files in git repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n files: {\\n type: 'array',\\n items: { type: 'string' }\\n }\\n },\\n required: ['files']\\n },\\n function: async (params: any) => {\\n try {\\n logger.debug(`Tool::Git Reverting files: ${params.files.join(', ')}`);\\n await git.checkout(['--', ...params.files]);\\n return {\\n success: true,\\n output: 'Files reverted successfully',\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error reverting files', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'switch_version',\\n description: 'Switch to previous version from remote',\\n parameters: {\\n type: 'object',\\n properties: {\\n branch: { type: 'string' },\\n remote: { \\n type: 'string',\\n default: 'origin'\\n }\\n },\\n required: ['branch']\\n },\\n function: async (params: any) => {\\n try {\\n const remote = params.remote || 'origin';\\n logger.debug(`Tool::Git Switching to branch ${params.branch} from ${remote}`);\\n const result = await git.checkout(`${remote}/${params.branch}`);\\n return {\\n success: true,\\n output: result,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error switching version', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'get_raw_file',\\n description: 'Retrieve raw content of a file from GitHub repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n url: { \\n type: 'string',\\n description: 'Full GitHub raw URL or repository path'\\n },\\n repo: {\\n type: 'string',\\n description: 'Repository in format owner/repo'\\n },\\n path: {\\n type: 'string',\\n description: 'File path within repository'\\n }\\n },\\n oneOf: [\\n { required: ['url'] },\\n { required: ['repo', 'path'] }\\n ]\\n },\\n function: async (params: any) => {\\n try {\\n let fileUrl = params.url;\\n if (!fileUrl && params.repo && params.path) {\\n fileUrl = `https://raw.githubusercontent.com/${params.repo}/main/${params.path}`;\\n }\\n \\n logger.debug(`Tool::Git Fetching raw file from ${fileUrl}`);\\n const response = await axios.get(fileUrl);\\n return {\\n success: true,\\n content: response.data,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error fetching raw file', error);\\n return {\\n success: false,\\n content: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { \\n FileListingOptionsSchema, \\n FileRemovalOptionsSchema,\\n GitCommitSchema,\\n GitRevertSchema,\\n GitSwitchVersionSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema,\\n TerminalCommandSchema \\n} from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n FileListingOptionsSchema,\\n FileRemovalOptionsSchema,\\n GitCommitSchema,\\n GitRevertSchema,\\n GitSwitchVersionSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema,\\n TerminalCommandSchema\\n ], 'src/zod_types.ts');\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\list.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { ListCommandSchema } from '../zod_schemas';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport type { Argv } from 'yargs';\\n\\nexport const options = (yargs: Argv) => toYargs(yargs, ListCommandSchema);\\n\\nexport const list = async (argv: any) => {\\n // Initialize tools with current directory\\n const fsTools = tools.fs(process.cwd());\\n const npmTools = tools.npm(process.cwd());\\n const gitTools = tools.git(process.cwd());\\n\\n const toolsList = {\\n fs: fsTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'fs'\\n })),\\n npm: npmTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'npm'\\n })),\\n git: gitTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'git'\\n }))\\n };\\n\\n logger.info('Available Tools:\\\\n');\\n \\n logger.info('Filesystem Tools:');\\n fsTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nNPM Tools:');\\n npmTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nGit Tools:');\\n gitTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n if (argv.output) {\\n logger.info(`\\\\nWriting tools list to ${argv.output}`);\\n write(argv.output, JSON.stringify(toolsList, null, 2));\\n }\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\invoke.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { InvokeToolSchema } from '../zod_schemas';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport type { Argv } from 'yargs';\\nimport * as path from 'path';\\n\\nconst options = (yargs: Argv) => toYargs(yargs, InvokeToolSchema);\\n\\nexport const invoke = async (argv: any) => {\\n try {\\n const { tools: toolCategory, function: funcName, target, params, output } = argv;\\n \\n // Get tool category\\n const toolSet = tools[toolCategory];\\n if (!toolSet) {\\n logger.error(`Tool category '${toolCategory}' not found`);\\n return;\\n }\\n\\n // Initialize tools with target directory\\n const toolList = toolSet(target);\\n \\n // Find specific function\\n const tool = toolList.find(t => t.function.name === funcName);\\n if (!tool) {\\n logger.error(`Function '${funcName}' not found in ${toolCategory} tools`);\\n return;\\n }\\n\\n // Parse parameters if provided\\n const parameters = params ? JSON.parse(params) : {};\\n \\n // Execute tool function\\n logger.info(`Invoking ${toolCategory}::${funcName}`);\\n const result = await tool.function.function(parameters);\\n \\n // Handle output\\n if (output) {\\n const outputPath = path.isAbsolute(output) ? output : path.join(process.cwd(), output);\\n logger.info(`Writing output to ${outputPath}`);\\n write(outputPath, JSON.stringify(result, null, 2));\\n } else {\\n logger.info('Result:', result);\\n }\\n \\n return result;\\n } catch (error) {\\n logger.error('Error invoking tool:', error);\\n throw error;\\n }\\n};\\n\\nexport { options as invokeOptions };\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\nimport { list, options as listOptions } from './list';\\nimport { invoke, invokeOptions } from './invoke';\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons';\\nimport { logger } from '../';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .command('list', 'List all available tools and their descriptions', listOptions, list)\\n .command('invoke', 'Invoke a specific tool function', invokeOptions, invoke)\\n .option('env_key', {\\n type: 'string',\\n description: 'Environment configuration key'\\n })\\n .middleware([(argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any;\\n if (!config) {\\n logger.warn('No config found!');\\n return;\\n }\\n return config;\\n }])\\n .strict()\\n .help();\\n};\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T13:28:32.891Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n### LLM Tools\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { resolve } from \"@plastichub/osr-commons\"\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any, variables:Record={}): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = path.resolve(resolve(join(target, file.path),false,variables))\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : Add support for background tasks in src/tools/terminal:execute_command, add option to run terminal in window\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\",\\n \\\"list\\\": \\\"ts-node src/main.ts list\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"simple-git\\\": \\\"^3.22.0\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nA command-line interface and library for Language Model tools with filesystem, npm, git, and terminal operations support.\\n\\n## Prerequisites\\n\\n- Node.js >= 16\\n- pnpm (recommended) or npm\\n- Git (for git operations)\\n\\n## Installation\\n\\n```bash\\n# Install globally\\npnpm add -g llm-tools-cli\\n\\n# Or install in project\\npnpm add llm-tools-cli\\n```\\n\\n## Quick Start\\n\\n```bash\\n# Initialize a new project\\npnpm init\\n\\n# Install dependencies\\npnpm install\\n\\n# Generate TypeScript types\\npnpm types\\n\\n# List available tools\\npnpm list\\n```\\n\\n## Configuration\\n\\nAPI keys and other settings can be configured using environment variables or a configuration file.\\n\\n```typescript\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\\n\\nexport const foo = (args) => {\\n const config = CONFIG_DEFAULT(args.env_key) as any\\n if (!config) {\\n logger.warn('No config found!')\\n return\\n }\\n if (config && !config.openai.key) {\\n logger.warn('No OpenAI key found in config!')\\n return\\n }\\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\\n}\\n```\\n\\n## Available Commands\\n\\n### Generate TypeScript Types\\n\\nGenerates TypeScript interfaces from all Zod schemas.\\n\\n```bash\\npnpm types\\n```\\n\\n### List Available Tools\\n\\nLists all available tools and their descriptions.\\n\\n```bash\\npnpm list [--output=./llm-tools.json]\\n```\\n\\n### Invoke Tool\\n\\nInvoke a specific tool function.\\n\\n```bash\\npnpm invoke --tools= --function= [options]\\n\\nOptions:\\n --tools Tool category (fs, npm, git, terminal)\\n --function Function name to invoke\\n --target Target directory [default: current]\\n --params JSON string of parameters\\n --output Output file path\\n --env_key Environment key\\n```\\n\\n## Tool Categories\\n\\n### Filesystem Tools\\n\\n```typescript\\nimport { sync as rm } from '@plastichub/fs/remove'\\nimport { sync as dir } from '@plastichub/fs/dir'\\nimport { sync as write } from '@plastichub/fs/write'\\nimport { sync as read } from '@plastichub/fs/read'\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob'\\n\\n// Example: List files\\npnpm invoke --tools=fs --function=list_files \\\\\\n --params='{\\\"directory\\\":\\\"src\\\",\\\"pattern\\\":\\\"**/*.ts\\\"}'\\n\\n// Example: Remove file\\npnpm invoke --tools=fs --function=remove_file \\\\\\n --params='{\\\"path\\\":\\\"temp.txt\\\"}'\\n```\\n\\n### Git Tools\\n\\n```typescript\\n// Example: Commit files\\npnpm invoke --tools=git --function=commit_files \\\\\\n --params='{\\\"files\\\":[\\\"src/main.ts\\\"],\\\"message\\\":\\\"Update code\\\"}'\\n\\n// Example: Revert files\\npnpm invoke --tools=git --function=revert_files \\\\\\n --params='{\\\"files\\\":[\\\"src/config.ts\\\"]}'\\n\\n// Example: Switch version\\npnpm invoke --tools=git --function=switch_version \\\\\\n --params='{\\\"branch\\\":\\\"main\\\",\\\"remote\\\":\\\"origin\\\"}'\\n\\n// Example: Get raw file\\npnpm invoke --tools=git --function=get_raw_file \\\\\\n --params='{\\\"repo\\\":\\\"owner/repo\\\",\\\"path\\\":\\\"file.ts\\\"}'\\n```\\n\\n### NPM Tools\\n\\n```typescript\\n// Example: Build project\\npnpm invoke --tools=npm --function=build_project\\n\\n// Example: Run npm command\\npnpm invoke --tools=npm --function=run_npm \\\\\\n --params='{\\\"command\\\":\\\"install\\\",\\\"args\\\":[\\\"--save-dev\\\",\\\"typescript\\\"]}'\\n```\\n\\n### Terminal Tools\\n\\n```typescript\\n// Example: Execute command\\npnpm invoke --tools=terminal --function=execute_command \\\\\\n --params='{\\\"command\\\":\\\"ls\\\",\\\"args\\\":[\\\"-la\\\"],\\\"cwd\\\":\\\"src\\\"}'\\n```\\n\\n## Library Usage\\n\\n### Logging\\n\\n```typescript\\nimport { Logger } from 'tslog'\\nimport { createLogger } from '@plastichub/osr-log'\\n\\nexport const logger: Logger = createLogger('package-name')\\n\\nlogger.info('Info message')\\nlogger.warn('Warning message')\\nlogger.error('Error message')\\n```\\n\\n### Zod Schemas and Yargs Integration\\n\\n```typescript\\nimport { z } from 'zod'\\nimport { toYargs } from '@plastichub/osr-commons'\\nimport type { Argv } from 'yargs'\\n\\n// Define schema\\nconst MySchema = z.object({\\n field: z.string().describe('Field description')\\n})\\n\\n// Convert to Yargs options\\nconst options = (yargs: Argv) => toYargs(yargs, MySchema)\\n```\\n\\n## Project Structure\\n\\n```\\nsrc/\\n├── index.ts # Logger setup\\n├── main.ts # CLI entry\\n├── constants.ts # Constants\\n├── tools.ts # Tool registry\\n├── zod_schemas.ts # Zod schemas\\n├── zod_types.ts # Generated types\\n├── commands/\\n│ ├── index.ts # Command registration\\n│ ├── list.ts # List command\\n│ ├── invoke.ts # Invoke command\\n│ └── types.ts # Types command\\n└── lib/\\n └── tools/\\n ├── fs.ts # Filesystem tools\\n ├── git.ts # Git tools\\n ├── npm.ts # NPM tools\\n └── terminal.ts # Terminal tools\\n```\\n\\n## Development\\n\\n```bash\\n# Clone repository\\ngit clone \\ncd llm-tools-cli\\n\\n# Install dependencies\\npnpm install\\n\\n# Build\\npnpm build\\n\\n# Run development version\\npnpm dev\\n\\n# Generate types\\npnpm types\\n```\\n\\n## Contributing\\n\\n1. Fork the repository\\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\\n3. Commit your changes (`git commit -m 'Add some amazing feature'`)\\n4. Push to the branch (`git push origin feature/amazing-feature`)\\n5. Open a Pull Request\\n\\n## License\\n\\nThis project is licensed under the MIT License.\\n\"\n },\n {\n \"path\": \"src\\\\zod_types.ts\",\n \"content\": \"export interface IOptions {\\n /** Directory path to list files from */\\n directory: string;\\n /** Glob pattern for filtering files */\\n pattern?: string | undefined;\\n}\\nexport interface IOptions {\\n /** Path of the file to remove */\\n path: string;\\n}\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\n/** Schema for listing files in a directory */\\nexport const FileListingOptionsSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n});\\n\\n/** Schema for file removal operations */\\nexport const FileRemovalOptionsSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n});\\n\\n/** Schema for git commit operations */\\nexport const GitCommitSchema = z.object({\\n files: z.array(z.string()).describe('Files to commit'),\\n message: z.string().describe('Commit message')\\n});\\n\\n/** Schema for git revert operations */\\nexport const GitRevertSchema = z.object({\\n files: z.array(z.string()).describe('Files to revert')\\n});\\n\\n/** Schema for git version switch operations */\\nexport const GitSwitchVersionSchema = z.object({\\n branch: z.string().describe('Branch name to switch to'),\\n remote: z.string().default('origin').describe('Remote name')\\n});\\n\\n/** Schema for git raw file retrieval */\\nexport const GitRawFileSchema = z.object({\\n url: z.string().optional().describe('Full GitHub raw URL'),\\n repo: z.string().optional().describe('Repository in format owner/repo'),\\n path: z.string().optional().describe('File path within repository')\\n}).refine(\\n data => (data.url) || (data.repo && data.path),\\n 'Either url or both repo and path must be provided'\\n);\\n\\n/** Schema for npm run command */\\nexport const NpmRunSchema = z.object({\\n command: z.string().describe('Command to run (e.g. install, test, etc)'),\\n args: z.array(z.string()).optional().describe('Additional arguments for the command')\\n});\\n\\n/** Schema for terminal command execution */\\nexport const TerminalCommandSchema = z.object({\\n command: z.string().describe('Command to execute'),\\n args: z.array(z.string()).optional().describe('Command arguments'),\\n cwd: z.string().optional().describe('Working directory for command execution')\\n});\\n\\n/** Schema for tool invocation parameters */\\nexport const InvokeToolSchema = z.object({\\n tools: z.string().describe('Tool category to use (fs, npm, git, terminal)'),\\n function: z.string().describe('Function name to invoke'),\\n target: z.string().default(process.cwd()).describe('Target directory'),\\n params: z.string().optional().describe('JSON string of parameters'),\\n output: z.string().optional().describe('Path to write the output to'),\\n env_key: z.string().optional().describe('Environment configuration key')\\n});\\n\\n/** Schema for list command options */\\nexport const ListCommandSchema = z.object({\\n output: z.string().default(\\\"./llm-tools.json\\\").describe('Output file path for tools list')\\n});\\n\\n/** Schema for tool listing options */\\nexport const ToolListingOptionsSchema = z.object({\\n output: z.string().default('./llm-tools.json').describe('Output file path for tools list')\\n});\"\n },\n {\n \"path\": \"src\\\\tools.ts\",\n \"content\": \"import { tools as fsTools } from './lib/tools/fs';\\nimport { tools as npmTools } from './lib/tools/npm';\\nimport { tools as gitTools } from './lib/tools/git';\\nimport { tools as terminalTools } from './lib/tools/terminal';\\n\\nexport const tools = {\\n fs: fsTools,\\n npm: npmTools,\\n git: gitTools,\\n terminal: terminalTools\\n};\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport yargs from 'yargs';\\nimport { commands } from './commands';\\nimport { logger } from './';\\n\\nasync function main() {\\n try {\\n const argv = await commands(yargs).argv;\\n } catch (error) {\\n logger.error('Error executing command:', error);\\n process.exit(1);\\n }\\n}\\n\\nmain();\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\terminal.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'execute_command',\\n description: 'Execute a terminal command and capture output',\\n parameters: {\\n type: 'object',\\n properties: {\\n command: { \\n type: 'string',\\n description: 'Command to execute'\\n },\\n args: {\\n type: 'array',\\n items: { type: 'string' },\\n description: 'Command arguments',\\n optional: true\\n },\\n cwd: {\\n type: 'string',\\n description: 'Working directory for command execution',\\n optional: true\\n }\\n },\\n required: ['command']\\n },\\n function: async (params: any) => {\\n try {\\n const workingDir = params.cwd ? path.join(target, params.cwd) : target;\\n const args = params.args ? params.args.join(' ') : '';\\n const fullCommand = `${params.command} ${args}`.trim();\\n \\n logger.debug(`Tool::ExecuteCommand Running '${fullCommand}' in ${workingDir}`);\\n const { stdout, stderr } = await execAsync(fullCommand, {\\n cwd: workingDir\\n });\\n\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error: any) {\\n logger.error('Error executing command', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\npm.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'build_project',\\n description: 'Build project using pnpm build command',\\n parameters: {\\n type: 'object',\\n properties: {},\\n required: []\\n },\\n function: async () => {\\n try {\\n logger.debug(`Tool::BuildProject Building project at ${target}`);\\n const { stdout, stderr } = await execAsync('pnpm build', {\\n cwd: target\\n });\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error : any) {\\n logger.error('Error building project', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'run_npm',\\n description: 'Run an npm/pnpm command',\\n parameters: {\\n type: 'object',\\n properties: {\\n command: { type: 'string', description: 'Command to run (e.g. install, test, etc)' },\\n args: { \\n type: 'array',\\n items: { type: 'string' },\\n description: 'Additional arguments for the command',\\n optional: true\\n }\\n },\\n required: ['command']\\n },\\n function: async (params: any) => {\\n try {\\n const args = params.args ? params.args.join(' ') : '';\\n const fullCommand = `pnpm ${params.command} ${args}`.trim();\\n logger.debug(`Tool::RunNpm Running command: ${fullCommand}`);\\n const { stdout, stderr } = await execAsync(fullCommand, {\\n cwd: target\\n });\\n\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error: any) {\\n logger.error('Error running npm command', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\git.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport simpleGit, { SimpleGit } from 'simple-git';\\nimport axios from 'axios';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n const git: SimpleGit = simpleGit(target);\\n\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'commit_files',\\n description: 'Commit files to git repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n files: {\\n type: 'array',\\n items: { type: 'string' }\\n },\\n message: { type: 'string' }\\n },\\n required: ['files', 'message']\\n },\\n function: async (params: any) => {\\n try {\\n logger.debug(`Tool::Git Committing files with message: ${params.message}`);\\n await git.add(params.files);\\n const result = await git.commit(params.message);\\n return {\\n success: true,\\n output: result,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error committing files', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'revert_files',\\n description: 'Revert specified files in git repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n files: {\\n type: 'array',\\n items: { type: 'string' }\\n }\\n },\\n required: ['files']\\n },\\n function: async (params: any) => {\\n try {\\n logger.debug(`Tool::Git Reverting files: ${params.files.join(', ')}`);\\n await git.checkout(['--', ...params.files]);\\n return {\\n success: true,\\n output: 'Files reverted successfully',\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error reverting files', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'switch_version',\\n description: 'Switch to previous version from remote',\\n parameters: {\\n type: 'object',\\n properties: {\\n branch: { type: 'string' },\\n remote: { \\n type: 'string',\\n default: 'origin'\\n }\\n },\\n required: ['branch']\\n },\\n function: async (params: any) => {\\n try {\\n const remote = params.remote || 'origin';\\n logger.debug(`Tool::Git Switching to branch ${params.branch} from ${remote}`);\\n const result = await git.checkout(`${remote}/${params.branch}`);\\n return {\\n success: true,\\n output: result,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error switching version', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'get_raw_file',\\n description: 'Retrieve raw content of a file from GitHub repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n url: { \\n type: 'string',\\n description: 'Full GitHub raw URL or repository path'\\n },\\n repo: {\\n type: 'string',\\n description: 'Repository in format owner/repo'\\n },\\n path: {\\n type: 'string',\\n description: 'File path within repository'\\n }\\n },\\n oneOf: [\\n { required: ['url'] },\\n { required: ['repo', 'path'] }\\n ]\\n },\\n function: async (params: any) => {\\n try {\\n let fileUrl = params.url;\\n if (!fileUrl && params.repo && params.path) {\\n fileUrl = `https://raw.githubusercontent.com/${params.repo}/main/${params.path}`;\\n }\\n \\n logger.debug(`Tool::Git Fetching raw file from ${fileUrl}`);\\n const response = await axios.get(fileUrl);\\n return {\\n success: true,\\n content: response.data,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error fetching raw file', error);\\n return {\\n success: false,\\n content: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { \\n FileListingOptionsSchema, \\n FileRemovalOptionsSchema,\\n GitCommitSchema,\\n GitRevertSchema,\\n GitSwitchVersionSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema,\\n TerminalCommandSchema \\n} from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n FileListingOptionsSchema,\\n FileRemovalOptionsSchema,\\n GitCommitSchema,\\n GitRevertSchema,\\n GitSwitchVersionSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema,\\n TerminalCommandSchema\\n ], 'src/zod_types.ts');\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\list.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { ListCommandSchema } from '../zod_schemas';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport type { Argv } from 'yargs';\\n\\nexport const options = (yargs: Argv) => toYargs(yargs, ListCommandSchema);\\n\\nexport const list = async (argv: any) => {\\n // Initialize tools with current directory\\n const fsTools = tools.fs(process.cwd());\\n const npmTools = tools.npm(process.cwd());\\n const gitTools = tools.git(process.cwd());\\n\\n const toolsList = {\\n fs: fsTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'fs'\\n })),\\n npm: npmTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'npm'\\n })),\\n git: gitTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'git'\\n }))\\n };\\n\\n logger.info('Available Tools:\\\\n');\\n \\n logger.info('Filesystem Tools:');\\n fsTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nNPM Tools:');\\n npmTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nGit Tools:');\\n gitTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n if (argv.output) {\\n logger.info(`\\\\nWriting tools list to ${argv.output}`);\\n write(argv.output, JSON.stringify(toolsList, null, 2));\\n }\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\invoke.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { InvokeToolSchema } from '../zod_schemas';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport type { Argv } from 'yargs';\\nimport * as path from 'path';\\n\\nconst options = (yargs: Argv) => toYargs(yargs, InvokeToolSchema);\\n\\nexport const invoke = async (argv: any) => {\\n try {\\n const { tools: toolCategory, function: funcName, target, params, output } = argv;\\n \\n // Get tool category\\n const toolSet = tools[toolCategory];\\n if (!toolSet) {\\n logger.error(`Tool category '${toolCategory}' not found`);\\n return;\\n }\\n\\n // Initialize tools with target directory\\n const toolList = toolSet(target);\\n \\n // Find specific function\\n const tool = toolList.find(t => t.function.name === funcName);\\n if (!tool) {\\n logger.error(`Function '${funcName}' not found in ${toolCategory} tools`);\\n return;\\n }\\n\\n // Parse parameters if provided\\n const parameters = params ? JSON.parse(params) : {};\\n \\n // Execute tool function\\n logger.info(`Invoking ${toolCategory}::${funcName}`);\\n const result = await tool.function.function(parameters);\\n \\n // Handle output\\n if (output) {\\n const outputPath = path.isAbsolute(output) ? output : path.join(process.cwd(), output);\\n logger.info(`Writing output to ${outputPath}`);\\n write(outputPath, JSON.stringify(result, null, 2));\\n } else {\\n logger.info('Result:', result);\\n }\\n \\n return result;\\n } catch (error) {\\n logger.error('Error invoking tool:', error);\\n throw error;\\n }\\n};\\n\\nexport { options as invokeOptions };\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\nimport { list, options as listOptions } from './list';\\nimport { invoke, invokeOptions } from './invoke';\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons';\\nimport { logger } from '../';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .command('list', 'List all available tools and their descriptions', listOptions, list)\\n .command('invoke', 'Invoke a specific tool function', invokeOptions, invoke)\\n .option('env_key', {\\n type: 'string',\\n description: 'Environment configuration key'\\n })\\n .middleware([(argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any;\\n if (!config) {\\n logger.warn('No config found!');\\n return;\\n }\\n return config;\\n }])\\n .strict()\\n .help();\\n};\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T13:31:26.101Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n### LLM Tools\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { resolve } from \"@plastichub/osr-commons\"\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any, variables:Record={}): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = path.resolve(resolve(join(target, file.path),false,variables))\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : Add terminal tools in src/commands/list\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\",\\n \\\"list\\\": \\\"ts-node src/main.ts list\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"simple-git\\\": \\\"^3.22.0\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nA command-line interface and library for Language Model tools with filesystem, npm, git, and terminal operations support.\\n\\n## Prerequisites\\n\\n- Node.js >= 16\\n- pnpm (recommended) or npm\\n- Git (for git operations)\\n\\n## Installation\\n\\n```bash\\n# Install globally\\npnpm add -g llm-tools-cli\\n\\n# Or install in project\\npnpm add llm-tools-cli\\n```\\n\\n## Quick Start\\n\\n```bash\\n# Initialize a new project\\npnpm init\\n\\n# Install dependencies\\npnpm install\\n\\n# Generate TypeScript types\\npnpm types\\n\\n# List available tools\\npnpm list\\n```\\n\\n## Configuration\\n\\nAPI keys and other settings can be configured using environment variables or a configuration file.\\n\\n```typescript\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\\n\\nexport const foo = (args) => {\\n const config = CONFIG_DEFAULT(args.env_key) as any\\n if (!config) {\\n logger.warn('No config found!')\\n return\\n }\\n if (config && !config.openai.key) {\\n logger.warn('No OpenAI key found in config!')\\n return\\n }\\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\\n}\\n```\\n\\n## Available Commands\\n\\n### Generate TypeScript Types\\n\\nGenerates TypeScript interfaces from all Zod schemas.\\n\\n```bash\\npnpm types\\n```\\n\\n### List Available Tools\\n\\nLists all available tools and their descriptions.\\n\\n```bash\\npnpm list [--output=./llm-tools.json]\\n```\\n\\n### Invoke Tool\\n\\nInvoke a specific tool function.\\n\\n```bash\\npnpm invoke --tools= --function= [options]\\n\\nOptions:\\n --tools Tool category (fs, npm, git, terminal)\\n --function Function name to invoke\\n --target Target directory [default: current]\\n --params JSON string of parameters\\n --output Output file path\\n --env_key Environment key\\n```\\n\\n## Tool Categories\\n\\n### Filesystem Tools\\n\\nOperations for file management using @plastichub/fs utilities.\\n\\n```typescript\\nimport { sync as rm } from '@plastichub/fs/remove'\\nimport { sync as dir } from '@plastichub/fs/dir'\\nimport { sync as write } from '@plastichub/fs/write'\\nimport { sync as read } from '@plastichub/fs/read'\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob'\\n\\n// Example: List files\\npnpm invoke --tools=fs --function=list_files \\\\\\n --params='{\\\"directory\\\":\\\"src\\\",\\\"pattern\\\":\\\"**/*.ts\\\"}'\\n\\n// Example: Remove file\\npnpm invoke --tools=fs --function=remove_file \\\\\\n --params='{\\\"path\\\":\\\"temp.txt\\\"}'\\n```\\n\\n### Git Tools\\n\\nGit repository operations including commit, revert, and version management.\\n\\n```typescript\\n// Example: Commit files\\npnpm invoke --tools=git --function=commit_files \\\\\\n --params='{\\\"files\\\":[\\\"src/main.ts\\\"],\\\"message\\\":\\\"Update code\\\"}'\\n\\n// Example: Revert files\\npnpm invoke --tools=git --function=revert_files \\\\\\n --params='{\\\"files\\\":[\\\"src/config.ts\\\"]}'\\n\\n// Example: Switch version\\npnpm invoke --tools=git --function=switch_version \\\\\\n --params='{\\\"branch\\\":\\\"main\\\",\\\"remote\\\":\\\"origin\\\"}'\\n\\n// Example: Get raw file\\npnpm invoke --tools=git --function=get_raw_file \\\\\\n --params='{\\\"repo\\\":\\\"owner/repo\\\",\\\"path\\\":\\\"file.ts\\\"}'\\n```\\n\\n### NPM Tools\\n\\nNPM/PNPM package management and script execution.\\n\\n```typescript\\n// Example: Build project\\npnpm invoke --tools=npm --function=build_project\\n\\n// Example: Run npm command\\npnpm invoke --tools=npm --function=run_npm \\\\\\n --params='{\\\"command\\\":\\\"install\\\",\\\"args\\\":[\\\"--save-dev\\\",\\\"typescript\\\"]}'\\n```\\n\\n### Terminal Tools\\n\\nAdvanced terminal command execution with support for background tasks and window options.\\n\\n```typescript\\n// Example: Execute command synchronously\\npnpm invoke --tools=terminal --function=execute_command \\\\\\n --params='{\\\"command\\\":\\\"ls\\\",\\\"args\\\":[\\\"-la\\\"],\\\"cwd\\\":\\\"src\\\"}'\\n\\n// Example: Run command in background\\npnpm invoke --tools=terminal --function=execute_command \\\\\\n --params='{\\\"command\\\":\\\"npm\\\",\\\"args\\\":[\\\"start\\\"],\\\"background\\\":true}'\\n\\n// Example: Open command in new window\\npnpm invoke --tools=terminal --function=execute_command \\\\\\n --params='{\\\"command\\\":\\\"vim\\\",\\\"args\\\":[\\\"file.txt\\\"],\\\"window\\\":true}'\\n\\n// Example: Run detached process\\npnpm invoke --tools=terminal --function=execute_command \\\\\\n --params='{\\\"command\\\":\\\"node\\\",\\\"args\\\":[\\\"server.js\\\"],\\\"detached\\\":true}'\\n```\\n\\n## Library Usage\\n\\n### Logging\\n\\nIntegrated logging using tslog.\\n\\n```typescript\\nimport { Logger } from 'tslog'\\nimport { createLogger } from '@plastichub/osr-log'\\n\\nexport const logger: Logger = createLogger('package-name')\\n\\nlogger.info('Info message')\\nlogger.warn('Warning message')\\nlogger.error('Error message')\\n```\\n\\n### Zod Schemas and Yargs Integration\\n\\nType-safe CLI arguments using Zod schemas.\\n\\n```typescript\\nimport { z } from 'zod'\\nimport { toYargs } from '@plastichub/osr-commons'\\nimport type { Argv } from 'yargs'\\n\\n// Define schema\\nconst MySchema = z.object({\\n field: z.string().describe('Field description')\\n})\\n\\n// Convert to Yargs options\\nconst options = (yargs: Argv) => toYargs(yargs, MySchema)\\n```\\n\\n## Project Structure\\n\\n```\\nsrc/\\n├── index.ts # Logger setup\\n├── main.ts # CLI entry\\n├── constants.ts # Constants\\n├── tools.ts # Tool registry\\n├── zod_schemas.ts # Zod schemas\\n├── zod_types.ts # Generated types\\n├── commands/\\n│ ├── index.ts # Command registration\\n│ ├── list.ts # List command\\n│ ├── invoke.ts # Invoke command\\n│ └── types.ts # Types command\\n└── lib/\\n └── tools/\\n ├── fs.ts # Filesystem tools\\n ├── git.ts # Git tools\\n ├── npm.ts # NPM tools\\n └── terminal.ts # Terminal tools\\n```\\n\\n## Development\\n\\n```bash\\n# Clone repository\\ngit clone \\ncd llm-tools-cli\\n\\n# Install dependencies\\npnpm install\\n\\n# Build\\npnpm build\\n\\n# Run development version\\npnpm dev\\n\\n# Generate types\\npnpm types\\n```\\n\\n## Contributing\\n\\n1. Fork the repository\\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\\n3. Commit your changes (`git commit -m 'Add some amazing feature'`)\\n4. Push to the branch (`git push origin feature/amazing-feature`)\\n5. Open a Pull Request\\n\\n## License\\n\\nThis project is licensed under the MIT License.\\n\"\n },\n {\n \"path\": \"src\\\\zod_types.ts\",\n \"content\": \"export interface IOptions {\\n /** Directory path to list files from */\\n directory: string;\\n /** Glob pattern for filtering files */\\n pattern?: string | undefined;\\n}\\nexport interface IOptions {\\n /** Path of the file to remove */\\n path: string;\\n}\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\n/** Schema for listing files in a directory */\\nexport const FileListingOptionsSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n});\\n\\n/** Schema for file removal operations */\\nexport const FileRemovalOptionsSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n});\\n\\n/** Schema for git commit operations */\\nexport const GitCommitSchema = z.object({\\n files: z.array(z.string()).describe('Files to commit'),\\n message: z.string().describe('Commit message')\\n});\\n\\n/** Schema for git revert operations */\\nexport const GitRevertSchema = z.object({\\n files: z.array(z.string()).describe('Files to revert')\\n});\\n\\n/** Schema for git version switch operations */\\nexport const GitSwitchVersionSchema = z.object({\\n branch: z.string().describe('Branch name to switch to'),\\n remote: z.string().default('origin').describe('Remote name')\\n});\\n\\n/** Schema for git raw file retrieval */\\nexport const GitRawFileSchema = z.object({\\n url: z.string().optional().describe('Full GitHub raw URL'),\\n repo: z.string().optional().describe('Repository in format owner/repo'),\\n path: z.string().optional().describe('File path within repository')\\n}).refine(\\n data => (data.url) || (data.repo && data.path),\\n 'Either url or both repo and path must be provided'\\n);\\n\\n/** Schema for npm run command */\\nexport const NpmRunSchema = z.object({\\n command: z.string().describe('Command to run (e.g. install, test, etc)'),\\n args: z.array(z.string()).optional().describe('Additional arguments for the command')\\n});\\n\\n/** Schema for terminal command execution */\\nexport const TerminalCommandSchema = z.object({\\n command: z.string().describe('Command to execute'),\\n args: z.array(z.string()).optional().describe('Command arguments'),\\n cwd: z.string().optional().describe('Working directory for command execution'),\\n background: z.boolean().optional().describe('Run command in background (non-blocking)'),\\n window: z.boolean().optional().describe('Open command in new terminal window'),\\n detached: z.boolean().optional().describe('Run process detached from parent')\\n});\\n\\n/** Schema for tool invocation parameters */\\nexport const InvokeToolSchema = z.object({\\n tools: z.string().describe('Tool category to use (fs, npm, git, terminal)'),\\n function: z.string().describe('Function name to invoke'),\\n target: z.string().default(process.cwd()).describe('Target directory'),\\n params: z.string().optional().describe('JSON string of parameters'),\\n output: z.string().optional().describe('Path to write the output to'),\\n env_key: z.string().optional().describe('Environment configuration key')\\n});\\n\\n/** Schema for list command options */\\nexport const ListCommandSchema = z.object({\\n output: z.string().default(\\\"./llm-tools.json\\\").describe('Output file path for tools list')\\n});\\n\\n/** Schema for tool listing options */\\nexport const ToolListingOptionsSchema = z.object({\\n output: z.string().default('./llm-tools.json').describe('Path to write the output to')\\n});\"\n },\n {\n \"path\": \"src\\\\tools.ts\",\n \"content\": \"import { tools as fsTools } from './lib/tools/fs';\\nimport { tools as npmTools } from './lib/tools/npm';\\nimport { tools as gitTools } from './lib/tools/git';\\nimport { tools as terminalTools } from './lib/tools/terminal';\\n\\nexport const tools = {\\n fs: fsTools,\\n npm: npmTools,\\n git: gitTools,\\n terminal: terminalTools\\n};\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport yargs from 'yargs';\\nimport { commands } from './commands';\\nimport { logger } from './';\\n\\nasync function main() {\\n try {\\n const argv = await commands(yargs).argv;\\n } catch (error) {\\n logger.error('Error executing command:', error);\\n process.exit(1);\\n }\\n}\\n\\nmain();\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\terminal.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec, spawn } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'execute_command',\\n description: 'Execute a terminal command and capture output',\\n parameters: {\\n type: 'object',\\n properties: {\\n command: { \\n type: 'string',\\n description: 'Command to execute'\\n },\\n args: {\\n type: 'array',\\n items: { type: 'string' },\\n description: 'Command arguments',\\n optional: true\\n },\\n cwd: {\\n type: 'string',\\n description: 'Working directory for command execution',\\n optional: true\\n },\\n background: {\\n type: 'boolean',\\n description: 'Run command in background (non-blocking)',\\n optional: true\\n },\\n window: {\\n type: 'boolean',\\n description: 'Open command in new terminal window',\\n optional: true\\n },\\n detached: {\\n type: 'boolean',\\n description: 'Run process detached from parent',\\n optional: true\\n }\\n },\\n required: ['command']\\n },\\n function: async (params: any) => {\\n try {\\n const workingDir = params.cwd ? path.join(target, params.cwd) : target;\\n const args = params.args || [];\\n \\n // Handle window mode (platform specific)\\n if (params.window) {\\n const isWindows = process.platform === 'win32';\\n if (isWindows) {\\n spawn('cmd', ['/c', 'start', 'cmd', '/k', params.command, ...args], {\\n cwd: workingDir,\\n detached: true,\\n stdio: 'ignore'\\n });\\n } else {\\n // For macOS/Linux\\n spawn('x-terminal-emulator', ['-e', `${params.command} ${args.join(' ')}`], {\\n cwd: workingDir,\\n detached: true,\\n stdio: 'ignore'\\n });\\n }\\n return {\\n success: true,\\n output: 'Command launched in new window',\\n error: null\\n };\\n }\\n\\n // Handle background/detached mode\\n if (params.background || params.detached) {\\n const child = spawn(params.command, args, {\\n cwd: workingDir,\\n detached: params.detached === true,\\n stdio: 'ignore'\\n });\\n\\n if (params.detached) {\\n child.unref();\\n }\\n\\n return {\\n success: true,\\n output: `Process started with PID: ${child.pid}`,\\n error: null\\n };\\n }\\n\\n // Regular synchronous execution\\n const fullCommand = `${params.command} ${args.join(' ')}`.trim();\\n logger.debug(`Tool::ExecuteCommand Running '${fullCommand}' in ${workingDir}`);\\n const { stdout, stderr } = await execAsync(fullCommand, {\\n cwd: workingDir\\n });\\n\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error: any) {\\n logger.error('Error executing command', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\npm.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'build_project',\\n description: 'Build project using pnpm build command',\\n parameters: {\\n type: 'object',\\n properties: {},\\n required: []\\n },\\n function: async () => {\\n try {\\n logger.debug(`Tool::BuildProject Building project at ${target}`);\\n const { stdout, stderr } = await execAsync('pnpm build', {\\n cwd: target\\n });\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error : any) {\\n logger.error('Error building project', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'run_npm',\\n description: 'Run an npm/pnpm command',\\n parameters: {\\n type: 'object',\\n properties: {\\n command: { type: 'string', description: 'Command to run (e.g. install, test, etc)' },\\n args: { \\n type: 'array',\\n items: { type: 'string' },\\n description: 'Additional arguments for the command',\\n optional: true\\n }\\n },\\n required: ['command']\\n },\\n function: async (params: any) => {\\n try {\\n const args = params.args ? params.args.join(' ') : '';\\n const fullCommand = `pnpm ${params.command} ${args}`.trim();\\n logger.debug(`Tool::RunNpm Running command: ${fullCommand}`);\\n const { stdout, stderr } = await execAsync(fullCommand, {\\n cwd: target\\n });\\n\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error: any) {\\n logger.error('Error running npm command', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\git.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport simpleGit, { SimpleGit } from 'simple-git';\\nimport axios from 'axios';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n const git: SimpleGit = simpleGit(target);\\n\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'commit_files',\\n description: 'Commit files to git repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n files: {\\n type: 'array',\\n items: { type: 'string' }\\n },\\n message: { type: 'string' }\\n },\\n required: ['files', 'message']\\n },\\n function: async (params: any) => {\\n try {\\n logger.debug(`Tool::Git Committing files with message: ${params.message}`);\\n await git.add(params.files);\\n const result = await git.commit(params.message);\\n return {\\n success: true,\\n output: result,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error committing files', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'revert_files',\\n description: 'Revert specified files in git repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n files: {\\n type: 'array',\\n items: { type: 'string' }\\n }\\n },\\n required: ['files']\\n },\\n function: async (params: any) => {\\n try {\\n logger.debug(`Tool::Git Reverting files: ${params.files.join(', ')}`);\\n await git.checkout(['--', ...params.files]);\\n return {\\n success: true,\\n output: 'Files reverted successfully',\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error reverting files', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'switch_version',\\n description: 'Switch to previous version from remote',\\n parameters: {\\n type: 'object',\\n properties: {\\n branch: { type: 'string' },\\n remote: { \\n type: 'string',\\n default: 'origin'\\n }\\n },\\n required: ['branch']\\n },\\n function: async (params: any) => {\\n try {\\n const remote = params.remote || 'origin';\\n logger.debug(`Tool::Git Switching to branch ${params.branch} from ${remote}`);\\n const result = await git.checkout(`${remote}/${params.branch}`);\\n return {\\n success: true,\\n output: result,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error switching version', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'get_raw_file',\\n description: 'Retrieve raw content of a file from GitHub repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n url: { \\n type: 'string',\\n description: 'Full GitHub raw URL or repository path'\\n },\\n repo: {\\n type: 'string',\\n description: 'Repository in format owner/repo'\\n },\\n path: {\\n type: 'string',\\n description: 'File path within repository'\\n }\\n },\\n oneOf: [\\n { required: ['url'] },\\n { required: ['repo', 'path'] }\\n ]\\n },\\n function: async (params: any) => {\\n try {\\n let fileUrl = params.url;\\n if (!fileUrl && params.repo && params.path) {\\n fileUrl = `https://raw.githubusercontent.com/${params.repo}/main/${params.path}`;\\n }\\n \\n logger.debug(`Tool::Git Fetching raw file from ${fileUrl}`);\\n const response = await axios.get(fileUrl);\\n return {\\n success: true,\\n content: response.data,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error fetching raw file', error);\\n return {\\n success: false,\\n content: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { \\n FileListingOptionsSchema, \\n FileRemovalOptionsSchema,\\n GitCommitSchema,\\n GitRevertSchema,\\n GitSwitchVersionSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema,\\n TerminalCommandSchema \\n} from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n FileListingOptionsSchema,\\n FileRemovalOptionsSchema,\\n GitCommitSchema,\\n GitRevertSchema,\\n GitSwitchVersionSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema,\\n TerminalCommandSchema\\n ], 'src/zod_types.ts');\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\list.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { ListCommandSchema } from '../zod_schemas';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport type { Argv } from 'yargs';\\n\\nexport const options = (yargs: Argv) => toYargs(yargs, ListCommandSchema);\\n\\nexport const list = async (argv: any) => {\\n // Initialize tools with current directory\\n const fsTools = tools.fs(process.cwd());\\n const npmTools = tools.npm(process.cwd());\\n const gitTools = tools.git(process.cwd());\\n\\n const toolsList = {\\n fs: fsTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'fs'\\n })),\\n npm: npmTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'npm'\\n })),\\n git: gitTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'git'\\n }))\\n };\\n\\n logger.info('Available Tools:\\\\n');\\n \\n logger.info('Filesystem Tools:');\\n fsTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nNPM Tools:');\\n npmTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nGit Tools:');\\n gitTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n if (argv.output) {\\n logger.info(`\\\\nWriting tools list to ${argv.output}`);\\n write(argv.output, JSON.stringify(toolsList, null, 2));\\n }\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\invoke.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { InvokeToolSchema } from '../zod_schemas';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport type { Argv } from 'yargs';\\nimport * as path from 'path';\\n\\nconst options = (yargs: Argv) => toYargs(yargs, InvokeToolSchema);\\n\\nexport const invoke = async (argv: any) => {\\n try {\\n const { tools: toolCategory, function: funcName, target, params, output } = argv;\\n \\n // Get tool category\\n const toolSet = tools[toolCategory];\\n if (!toolSet) {\\n logger.error(`Tool category '${toolCategory}' not found`);\\n return;\\n }\\n\\n // Initialize tools with target directory\\n const toolList = toolSet(target);\\n \\n // Find specific function\\n const tool = toolList.find(t => t.function.name === funcName);\\n if (!tool) {\\n logger.error(`Function '${funcName}' not found in ${toolCategory} tools`);\\n return;\\n }\\n\\n // Parse parameters if provided\\n const parameters = params ? JSON.parse(params) : {};\\n \\n // Execute tool function\\n logger.info(`Invoking ${toolCategory}::${funcName}`);\\n const result = await tool.function.function(parameters);\\n \\n // Handle output\\n if (output) {\\n const outputPath = path.isAbsolute(output) ? output : path.join(process.cwd(), output);\\n logger.info(`Writing output to ${outputPath}`);\\n write(outputPath, JSON.stringify(result, null, 2));\\n } else {\\n logger.info('Result:', result);\\n }\\n \\n return result;\\n } catch (error) {\\n logger.error('Error invoking tool:', error);\\n throw error;\\n }\\n};\\n\\nexport { options as invokeOptions };\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\nimport { list, options as listOptions } from './list';\\nimport { invoke, invokeOptions } from './invoke';\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons';\\nimport { logger } from '../';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .command('list', 'List all available tools and their descriptions', listOptions, list)\\n .command('invoke', 'Invoke a specific tool function', invokeOptions, invoke)\\n .option('env_key', {\\n type: 'string',\\n description: 'Environment configuration key'\\n })\\n .middleware([(argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any;\\n if (!config) {\\n logger.warn('No config found!');\\n return;\\n }\\n return config;\\n }])\\n .strict()\\n .help();\\n};\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T13:32:47.378Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n### LLM Tools\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { resolve } from \"@plastichub/osr-commons\"\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any, variables:Record={}): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = path.resolve(resolve(join(target, file.path),false,variables))\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : Add tools from src/tools/terminal in src/commands/list\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\",\\n \\\"list\\\": \\\"ts-node src/main.ts list\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"simple-git\\\": \\\"^3.22.0\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nA command-line interface and library for Language Model tools with filesystem, npm, git, and terminal operations support.\\n\\n## Features\\n\\n- Filesystem operations (list files, remove files)\\n- Git operations (commit, revert, version management)\\n- NPM/PNPM operations (build, run commands)\\n- Terminal command execution\\n- TypeScript interface generation from Zod schemas\\n\\n## Prerequisites\\n\\n- Node.js >= 16\\n- pnpm (recommended) or npm\\n- Git (for git operations)\\n\\n## Installation\\n\\n```bash\\n# Clone the repository\\ngit clone \\ncd llm-tools-cli\\n\\n# Install dependencies\\npnpm install\\n\\n# Build the project\\npnpm build\\n```\\n\\n## Command Line Usage\\n\\n### Generate TypeScript Types\\n\\nGenerates TypeScript interfaces from Zod schemas:\\n\\n```bash\\npnpm types\\n```\\n\\n### List Available Tools\\n\\nList all available tools and their descriptions:\\n\\n```bash\\npnpm list [--output=./llm-tools.json]\\n```\\n\\n### Invoke Tool\\n\\nInvoke a specific tool function:\\n\\n```bash\\npnpm invoke --tools= --function= [options]\\n\\nOptions:\\n --tools Tool category (fs, npm, git, terminal)\\n --function Function name to invoke\\n --target Target directory [default: current]\\n --params JSON string of parameters\\n --output Output file path\\n --env_key Environment key\\n```\\n\\n## Library Usage\\n\\n### Filesystem Operations\\n\\n```typescript\\nimport { sync as rm } from '@plastichub/fs/remove'\\nimport { sync as dir } from '@plastichub/fs/dir'\\nimport { sync as write } from '@plastichub/fs/write'\\nimport { sync as read } from '@plastichub/fs/read'\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob'\\n\\n// List files\\nawait invoke({\\n tools: 'fs',\\n function: 'list_files',\\n params: JSON.stringify({\\n directory: 'src',\\n pattern: '**/*.ts'\\n })\\n})\\n\\n// Remove file\\nawait invoke({\\n tools: 'fs',\\n function: 'remove_file',\\n params: JSON.stringify({\\n path: 'temp.txt'\\n })\\n})\\n```\\n\\n### Git Operations\\n\\n```typescript\\n// Commit files\\nawait invoke({\\n tools: 'git',\\n function: 'commit_files',\\n params: JSON.stringify({\\n files: ['src/main.ts'],\\n message: 'Update code'\\n })\\n})\\n\\n// Revert files\\nawait invoke({\\n tools: 'git',\\n function: 'revert_files',\\n params: JSON.stringify({\\n files: ['src/config.ts']\\n })\\n})\\n\\n// Switch version\\nawait invoke({\\n tools: 'git',\\n function: 'switch_version',\\n params: JSON.stringify({\\n branch: 'main',\\n remote: 'origin'\\n })\\n})\\n```\\n\\n### NPM Operations\\n\\n```typescript\\n// Build project\\nawait invoke({\\n tools: 'npm',\\n function: 'build_project'\\n})\\n\\n// Run npm command\\nawait invoke({\\n tools: 'npm',\\n function: 'run_npm',\\n params: JSON.stringify({\\n command: 'install',\\n args: ['--save-dev', 'typescript']\\n })\\n})\\n```\\n\\n### Terminal Operations\\n\\n```typescript\\n// Execute command\\nawait invoke({\\n tools: 'terminal',\\n function: 'execute_command',\\n params: JSON.stringify({\\n command: 'ls',\\n args: ['-la'],\\n cwd: 'src'\\n })\\n})\\n\\n// Run in background\\nawait invoke({\\n tools: 'terminal',\\n function: 'execute_command',\\n params: JSON.stringify({\\n command: 'npm',\\n args: ['start'],\\n background: true\\n })\\n})\\n```\\n\\n### Configuration\\n\\nAPI keys and other settings can be configured using environment variables or a configuration file:\\n\\n```typescript\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\\n\\nexport const example = (args) => {\\n const config = CONFIG_DEFAULT(args.env_key) as any\\n if (!config) {\\n logger.warn('No config found!')\\n return\\n }\\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\\n}\\n```\\n\\n### Logging\\n\\nIntegrated logging using tslog:\\n\\n```typescript\\nimport { Logger } from 'tslog'\\nimport { createLogger } from '@plastichub/osr-log'\\n\\nexport const logger: Logger = createLogger('package-name')\\n\\nlogger.info('Info message')\\nlogger.warn('Warning message')\\nlogger.error('Error message')\\n```\\n\\n### Zod Schemas\\n\\nType-safe CLI arguments using Zod schemas:\\n\\n```typescript\\nimport { z } from 'zod'\\nimport { toYargs } from '@plastichub/osr-commons'\\nimport type { Argv } from 'yargs'\\n\\n// Define schema\\nconst MySchema = z.object({\\n field: z.string().describe('Field description')\\n})\\n\\n// Convert to Yargs options\\nconst options = (yargs: Argv) => toYargs(yargs, MySchema)\\n```\\n\\n## Project Structure\\n\\n```\\nsrc/\\n├── index.ts # Logger setup\\n├── main.ts # CLI entry\\n├── constants.ts # Constants\\n├── tools.ts # Tool registry\\n├── zod_schemas.ts # Zod schemas\\n├── zod_types.ts # Generated types\\n├── commands/\\n│ ├── index.ts # Command registration\\n│ ├── list.ts # List command\\n│ ├── invoke.ts # Invoke command\\n│ └── types.ts # Types command\\n└── lib/\\n └── tools/\\n ├── fs.ts # Filesystem tools\\n ├── git.ts # Git tools\\n ├── npm.ts # NPM tools\\n └── terminal.ts # Terminal tools\\n```\\n\\n## Contributing\\n\\n1. Fork the repository\\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\\n3. Commit your changes (`git commit -m 'Add some amazing feature'`)\\n4. Push to the branch (`git push origin feature/amazing-feature`)\\n5. Open a Pull Request\\n\\n## License\\n\\nThis project is licensed under the MIT License.\\n\"\n },\n {\n \"path\": \"src\\\\zod_types.ts\",\n \"content\": \"export interface IOptions {\\n /** Directory path to list files from */\\n directory: string;\\n /** Glob pattern for filtering files */\\n pattern?: string | undefined;\\n}\\nexport interface IOptions {\\n /** Path of the file to remove */\\n path: string;\\n}\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\n/** Schema for listing files in a directory */\\nexport const FileListingOptionsSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n});\\n\\n/** Schema for file removal operations */\\nexport const FileRemovalOptionsSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n});\\n\\n/** Schema for git commit operations */\\nexport const GitCommitSchema = z.object({\\n files: z.array(z.string()).describe('Files to commit'),\\n message: z.string().describe('Commit message')\\n});\\n\\n/** Schema for git revert operations */\\nexport const GitRevertSchema = z.object({\\n files: z.array(z.string()).describe('Files to revert')\\n});\\n\\n/** Schema for git version switch operations */\\nexport const GitSwitchVersionSchema = z.object({\\n branch: z.string().describe('Branch name to switch to'),\\n remote: z.string().default('origin').describe('Remote name')\\n});\\n\\n/** Schema for git raw file retrieval */\\nexport const GitRawFileSchema = z.object({\\n url: z.string().optional().describe('Full GitHub raw URL'),\\n repo: z.string().optional().describe('Repository in format owner/repo'),\\n path: z.string().optional().describe('File path within repository')\\n}).refine(\\n data => (data.url) || (data.repo && data.path),\\n 'Either url or both repo and path must be provided'\\n);\\n\\n/** Schema for npm run command */\\nexport const NpmRunSchema = z.object({\\n command: z.string().describe('Command to run (e.g. install, test, etc)'),\\n args: z.array(z.string()).optional().describe('Additional arguments for the command')\\n});\\n\\n/** Schema for terminal command execution */\\nexport const TerminalCommandSchema = z.object({\\n command: z.string().describe('Command to execute'),\\n args: z.array(z.string()).optional().describe('Command arguments'),\\n cwd: z.string().optional().describe('Working directory for command execution'),\\n background: z.boolean().optional().describe('Run command in background (non-blocking)'),\\n window: z.boolean().optional().describe('Open command in new terminal window'),\\n detached: z.boolean().optional().describe('Run process detached from parent')\\n});\\n\\n/** Schema for tool invocation parameters */\\nexport const InvokeToolSchema = z.object({\\n tools: z.string().describe('Tool category to use (fs, npm, git, terminal)'),\\n function: z.string().describe('Function name to invoke'),\\n target: z.string().default(process.cwd()).describe('Target directory'),\\n params: z.string().optional().describe('JSON string of parameters'),\\n output: z.string().optional().describe('Path to write the output to'),\\n env_key: z.string().optional().describe('Environment configuration key')\\n});\\n\\n/** Schema for list command options */\\nexport const ListCommandSchema = z.object({\\n output: z.string().default(\\\"./llm-tools.json\\\").describe('Output file path for tools list')\\n});\\n\\n/** Schema for tool listing options */\\nexport const ToolListingOptionsSchema = z.object({\\n output: z.string().default('./llm-tools.json').describe('Path to write the output to')\\n});\"\n },\n {\n \"path\": \"src\\\\tools.ts\",\n \"content\": \"import { tools as fsTools } from './lib/tools/fs';\\nimport { tools as npmTools } from './lib/tools/npm';\\nimport { tools as gitTools } from './lib/tools/git';\\nimport { tools as terminalTools } from './lib/tools/terminal';\\n\\nexport const tools = {\\n fs: fsTools,\\n npm: npmTools,\\n git: gitTools,\\n terminal: terminalTools\\n};\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport yargs from 'yargs';\\nimport { commands } from './commands';\\nimport { logger } from './';\\n\\nasync function main() {\\n try {\\n const argv = await commands(yargs).argv;\\n } catch (error) {\\n logger.error('Error executing command:', error);\\n process.exit(1);\\n }\\n}\\n\\nmain();\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\terminal.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec, spawn } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'execute_command',\\n description: 'Execute a terminal command and capture output',\\n parameters: {\\n type: 'object',\\n properties: {\\n command: { \\n type: 'string',\\n description: 'Command to execute'\\n },\\n args: {\\n type: 'array',\\n items: { type: 'string' },\\n description: 'Command arguments',\\n optional: true\\n },\\n cwd: {\\n type: 'string',\\n description: 'Working directory for command execution',\\n optional: true\\n },\\n background: {\\n type: 'boolean',\\n description: 'Run command in background (non-blocking)',\\n optional: true\\n },\\n window: {\\n type: 'boolean',\\n description: 'Open command in new terminal window',\\n optional: true\\n },\\n detached: {\\n type: 'boolean',\\n description: 'Run process detached from parent',\\n optional: true\\n }\\n },\\n required: ['command']\\n },\\n function: async (params: any) => {\\n try {\\n const workingDir = params.cwd ? path.join(target, params.cwd) : target;\\n const args = params.args || [];\\n \\n // Handle window mode (platform specific)\\n if (params.window) {\\n const isWindows = process.platform === 'win32';\\n if (isWindows) {\\n spawn('cmd', ['/c', 'start', 'cmd', '/k', params.command, ...args], {\\n cwd: workingDir,\\n detached: true,\\n stdio: 'ignore'\\n });\\n } else {\\n // For macOS/Linux\\n spawn('x-terminal-emulator', ['-e', `${params.command} ${args.join(' ')}`], {\\n cwd: workingDir,\\n detached: true,\\n stdio: 'ignore'\\n });\\n }\\n return {\\n success: true,\\n output: 'Command launched in new window',\\n error: null\\n };\\n }\\n\\n // Handle background/detached mode\\n if (params.background || params.detached) {\\n const child = spawn(params.command, args, {\\n cwd: workingDir,\\n detached: params.detached === true,\\n stdio: 'ignore'\\n });\\n\\n if (params.detached) {\\n child.unref();\\n }\\n\\n return {\\n success: true,\\n output: `Process started with PID: ${child.pid}`,\\n error: null\\n };\\n }\\n\\n // Regular synchronous execution\\n const fullCommand = `${params.command} ${args.join(' ')}`.trim();\\n logger.debug(`Tool::ExecuteCommand Running '${fullCommand}' in ${workingDir}`);\\n const { stdout, stderr } = await execAsync(fullCommand, {\\n cwd: workingDir\\n });\\n\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error: any) {\\n logger.error('Error executing command', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\npm.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'build_project',\\n description: 'Build project using pnpm build command',\\n parameters: {\\n type: 'object',\\n properties: {},\\n required: []\\n },\\n function: async () => {\\n try {\\n logger.debug(`Tool::BuildProject Building project at ${target}`);\\n const { stdout, stderr } = await execAsync('pnpm build', {\\n cwd: target\\n });\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error : any) {\\n logger.error('Error building project', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'run_npm',\\n description: 'Run an npm/pnpm command',\\n parameters: {\\n type: 'object',\\n properties: {\\n command: { type: 'string', description: 'Command to run (e.g. install, test, etc)' },\\n args: { \\n type: 'array',\\n items: { type: 'string' },\\n description: 'Additional arguments for the command',\\n optional: true\\n }\\n },\\n required: ['command']\\n },\\n function: async (params: any) => {\\n try {\\n const args = params.args ? params.args.join(' ') : '';\\n const fullCommand = `pnpm ${params.command} ${args}`.trim();\\n logger.debug(`Tool::RunNpm Running command: ${fullCommand}`);\\n const { stdout, stderr } = await execAsync(fullCommand, {\\n cwd: target\\n });\\n\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error: any) {\\n logger.error('Error running npm command', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\git.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport simpleGit, { SimpleGit } from 'simple-git';\\nimport axios from 'axios';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n const git: SimpleGit = simpleGit(target);\\n\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'commit_files',\\n description: 'Commit files to git repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n files: {\\n type: 'array',\\n items: { type: 'string' }\\n },\\n message: { type: 'string' }\\n },\\n required: ['files', 'message']\\n },\\n function: async (params: any) => {\\n try {\\n logger.debug(`Tool::Git Committing files with message: ${params.message}`);\\n await git.add(params.files);\\n const result = await git.commit(params.message);\\n return {\\n success: true,\\n output: result,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error committing files', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'revert_files',\\n description: 'Revert specified files in git repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n files: {\\n type: 'array',\\n items: { type: 'string' }\\n }\\n },\\n required: ['files']\\n },\\n function: async (params: any) => {\\n try {\\n logger.debug(`Tool::Git Reverting files: ${params.files.join(', ')}`);\\n await git.checkout(['--', ...params.files]);\\n return {\\n success: true,\\n output: 'Files reverted successfully',\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error reverting files', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'switch_version',\\n description: 'Switch to previous version from remote',\\n parameters: {\\n type: 'object',\\n properties: {\\n branch: { type: 'string' },\\n remote: { \\n type: 'string',\\n default: 'origin'\\n }\\n },\\n required: ['branch']\\n },\\n function: async (params: any) => {\\n try {\\n const remote = params.remote || 'origin';\\n logger.debug(`Tool::Git Switching to branch ${params.branch} from ${remote}`);\\n const result = await git.checkout(`${remote}/${params.branch}`);\\n return {\\n success: true,\\n output: result,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error switching version', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'get_raw_file',\\n description: 'Retrieve raw content of a file from GitHub repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n url: { \\n type: 'string',\\n description: 'Full GitHub raw URL or repository path'\\n },\\n repo: {\\n type: 'string',\\n description: 'Repository in format owner/repo'\\n },\\n path: {\\n type: 'string',\\n description: 'File path within repository'\\n }\\n },\\n oneOf: [\\n { required: ['url'] },\\n { required: ['repo', 'path'] }\\n ]\\n },\\n function: async (params: any) => {\\n try {\\n let fileUrl = params.url;\\n if (!fileUrl && params.repo && params.path) {\\n fileUrl = `https://raw.githubusercontent.com/${params.repo}/main/${params.path}`;\\n }\\n \\n logger.debug(`Tool::Git Fetching raw file from ${fileUrl}`);\\n const response = await axios.get(fileUrl);\\n return {\\n success: true,\\n content: response.data,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error fetching raw file', error);\\n return {\\n success: false,\\n content: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { \\n FileListingOptionsSchema, \\n FileRemovalOptionsSchema,\\n GitCommitSchema,\\n GitRevertSchema,\\n GitSwitchVersionSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema,\\n TerminalCommandSchema \\n} from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n FileListingOptionsSchema,\\n FileRemovalOptionsSchema,\\n GitCommitSchema,\\n GitRevertSchema,\\n GitSwitchVersionSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema,\\n TerminalCommandSchema\\n ], 'src/zod_types.ts');\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\list.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { ListCommandSchema } from '../zod_schemas';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport type { Argv } from 'yargs';\\n\\nexport const options = (yargs: Argv) => toYargs(yargs, ListCommandSchema);\\n\\nexport const list = async (argv: any) => {\\n // Initialize tools with current directory\\n const fsTools = tools.fs(process.cwd());\\n const npmTools = tools.npm(process.cwd());\\n const gitTools = tools.git(process.cwd());\\n\\n const toolsList = {\\n fs: fsTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'fs'\\n })),\\n npm: npmTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'npm'\\n })),\\n git: gitTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'git'\\n }))\\n };\\n\\n logger.info('Available Tools:\\\\n');\\n \\n logger.info('Filesystem Tools:');\\n fsTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nNPM Tools:');\\n npmTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nGit Tools:');\\n gitTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n if (argv.output) {\\n logger.info(`\\\\nWriting tools list to ${argv.output}`);\\n write(argv.output, JSON.stringify(toolsList, null, 2));\\n }\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\invoke.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { InvokeToolSchema } from '../zod_schemas';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport type { Argv } from 'yargs';\\nimport * as path from 'path';\\n\\nconst options = (yargs: Argv) => toYargs(yargs, InvokeToolSchema);\\n\\nexport const invoke = async (argv: any) => {\\n try {\\n const { tools: toolCategory, function: funcName, target, params, output } = argv;\\n \\n // Get tool category\\n const toolSet = tools[toolCategory];\\n if (!toolSet) {\\n logger.error(`Tool category '${toolCategory}' not found`);\\n return;\\n }\\n\\n // Initialize tools with target directory\\n const toolList = toolSet(target);\\n \\n // Find specific function\\n const tool = toolList.find(t => t.function.name === funcName);\\n if (!tool) {\\n logger.error(`Function '${funcName}' not found in ${toolCategory} tools`);\\n return;\\n }\\n\\n // Parse parameters if provided\\n const parameters = params ? JSON.parse(params) : {};\\n \\n // Execute tool function\\n logger.info(`Invoking ${toolCategory}::${funcName}`);\\n const result = await tool.function.function(parameters);\\n \\n // Handle output\\n if (output) {\\n const outputPath = path.isAbsolute(output) ? output : path.join(process.cwd(), output);\\n logger.info(`Writing output to ${outputPath}`);\\n write(outputPath, JSON.stringify(result, null, 2));\\n } else {\\n logger.info('Result:', result);\\n }\\n \\n return result;\\n } catch (error) {\\n logger.error('Error invoking tool:', error);\\n throw error;\\n }\\n};\\n\\nexport { options as invokeOptions };\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\nimport { list, options as listOptions } from './list';\\nimport { invoke, invokeOptions } from './invoke';\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons';\\nimport { logger } from '../';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .command('list', 'List all available tools and their descriptions', listOptions, list)\\n .command('invoke', 'Invoke a specific tool function', invokeOptions, invoke)\\n .option('env_key', {\\n type: 'string',\\n description: 'Environment configuration key'\\n })\\n .middleware([(argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any;\\n if (!config) {\\n logger.warn('No config found!');\\n return;\\n }\\n return config;\\n }])\\n .strict()\\n .help();\\n};\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T13:34:33.682Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n### LLM Tools\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { resolve } from \"@plastichub/osr-commons\"\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any, variables:Record={}): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = path.resolve(resolve(join(target, file.path),false,variables))\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : Add names to src/zod_schemas.ts, eg : using .describe('IInvokeSchema')\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\",\\n \\\"list\\\": \\\"ts-node src/main.ts list\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"simple-git\\\": \\\"^3.22.0\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nA command-line interface and library for Language Model tools with filesystem, npm, git, and terminal operations support.\\n\\n## Features\\n\\n- Filesystem operations (list files, remove files)\\n- Git operations (commit, revert, version management)\\n- NPM/PNPM operations (build, run commands)\\n- Terminal command execution (sync/async, background, window modes)\\n- TypeScript interface generation from Zod schemas\\n\\n## Prerequisites\\n\\n- Node.js >= 16\\n- pnpm (recommended) or npm\\n- Git (for git operations)\\n\\n## Installation\\n\\n```bash\\n# Clone the repository\\ngit clone \\ncd llm-tools-cli\\n\\n# Install dependencies\\npnpm install\\n\\n# Build the project\\npnpm build\\n```\\n\\n## Environment Configuration\\n\\nThe CLI supports configuration via environment files or variables:\\n\\n1. Create a `.env` file or set environment variables:\\n ```env\\n OPENAI_API_KEY=your-api-key-here\\n ```\\n\\n2. Or use config files with `--env_key`:\\n ```bash\\n llm-tools invoke --env_key=production ...\\n ```\\n\\n## Command Line Usage\\n\\n### List Available Tools\\n\\nList all available tools and their descriptions:\\n\\n```bash\\npnpm list [--output=./llm-tools.json]\\n```\\n\\n### Generate TypeScript Types\\n\\nGenerates TypeScript interfaces from Zod schemas:\\n\\n```bash\\npnpm types\\n```\\n\\n### Invoke Tool\\n\\nInvoke a specific tool function:\\n\\n```bash\\npnpm invoke --tools= --function= [options]\\n\\nOptions:\\n --tools Tool category (fs, npm, git, terminal)\\n --function Function name to invoke\\n --target Target directory [default: current]\\n --params JSON string of parameters\\n --output Output file path\\n --env_key Environment key\\n```\\n\\n## Available Tools\\n\\n### Filesystem Tools\\n\\n```typescript\\n// List files in directory\\nawait invoke({\\n tools: 'fs',\\n function: 'list_files',\\n params: JSON.stringify({\\n directory: 'src',\\n pattern: '**/*.ts'\\n })\\n})\\n\\n// Remove file\\nawait invoke({\\n tools: 'fs',\\n function: 'remove_file',\\n params: JSON.stringify({\\n path: 'temp.txt'\\n })\\n})\\n```\\n\\n### Git Tools\\n\\n```typescript\\n// Commit files\\nawait invoke({\\n tools: 'git',\\n function: 'commit_files',\\n params: JSON.stringify({\\n files: ['src/main.ts'],\\n message: 'Update code'\\n })\\n})\\n\\n// Revert files\\nawait invoke({\\n tools: 'git',\\n function: 'revert_files',\\n params: JSON.stringify({\\n files: ['src/config.ts']\\n })\\n})\\n\\n// Switch version\\nawait invoke({\\n tools: 'git',\\n function: 'switch_version',\\n params: JSON.stringify({\\n branch: 'main',\\n remote: 'origin'\\n })\\n})\\n\\n// Get raw file from GitHub\\nawait invoke({\\n tools: 'git',\\n function: 'get_raw_file',\\n params: JSON.stringify({\\n repo: 'owner/repo',\\n path: 'path/to/file.ts'\\n })\\n})\\n```\\n\\n### NPM Tools\\n\\n```typescript\\n// Build project\\nawait invoke({\\n tools: 'npm',\\n function: 'build_project'\\n})\\n\\n// Run npm command\\nawait invoke({\\n tools: 'npm',\\n function: 'run_npm',\\n params: JSON.stringify({\\n command: 'install',\\n args: ['--save-dev', 'typescript']\\n })\\n})\\n```\\n\\n### Terminal Tools\\n\\n```typescript\\n// Execute command synchronously\\nawait invoke({\\n tools: 'terminal',\\n function: 'execute_command',\\n params: JSON.stringify({\\n command: 'ls',\\n args: ['-la'],\\n cwd: 'src'\\n })\\n})\\n\\n// Run in background\\nawait invoke({\\n tools: 'terminal',\\n function: 'execute_command',\\n params: JSON.stringify({\\n command: 'npm',\\n args: ['start'],\\n background: true\\n })\\n})\\n\\n// Open in new window\\nawait invoke({\\n tools: 'terminal',\\n function: 'execute_command',\\n params: JSON.stringify({\\n command: 'vim',\\n args: ['file.txt'],\\n window: true\\n })\\n})\\n```\\n\\n## Using as a Library\\n\\n### Setting up Logger\\n\\n```typescript\\nimport { Logger } from 'tslog'\\nimport { createLogger } from '@plastichub/osr-log'\\n\\nexport const logger: Logger = createLogger('package-name')\\n```\\n\\n### Type-safe CLI Arguments\\n\\n```typescript\\nimport { z } from 'zod'\\nimport { toYargs } from '@plastichub/osr-commons'\\nimport type { Argv } from 'yargs'\\n\\nconst MySchema = z.object({\\n directory: z.string().describe('Directory path')\\n})\\n\\nconst options = (yargs: Argv) => toYargs(yargs, MySchema)\\n```\\n\\n### Configuration Management\\n\\n```typescript\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\\n\\nexport const example = (argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any\\n if (!config) {\\n logger.warn('No config found!')\\n return\\n }\\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\\n}\\n```\\n\\n### Using Custom Filesystem Operations\\n\\n```typescript\\nimport { sync as rm } from '@plastichub/fs/remove'\\nimport { sync as dir } from '@plastichub/fs/dir'\\nimport { sync as write } from '@plastichub/fs/write'\\nimport { sync as read } from '@plastichub/fs/read'\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob'\\n\\n// Create directory\\ndir('path/to/dir')\\n\\n// Write file\\nwrite('file.txt', 'content')\\n\\n// Read file\\nconst content = read('file.txt')\\n\\n// Remove file\\nrm('file.txt')\\n\\n// List files\\nconst files = glob('src', ['**/*.ts'])\\n```\\n\\n## Contributing\\n\\n1. Fork the repository\\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\\n3. Commit changes (`git commit -m 'Add amazing feature'`)\\n4. Push to branch (`git push origin feature/amazing-feature`)\\n5. Open a Pull Request\\n\\n## License\\n\\nThis project is licensed under the MIT License.\\n\"\n },\n {\n \"path\": \"src\\\\zod_types.ts\",\n \"content\": \"export interface IOptions {\\n /** Directory path to list files from */\\n directory: string;\\n /** Glob pattern for filtering files */\\n pattern?: string | undefined;\\n}\\nexport interface IOptions {\\n /** Path of the file to remove */\\n path: string;\\n}\\nexport interface IOptions {\\n /** Files to commit */\\n files: string[];\\n /** Commit message */\\n message: string;\\n}\\nexport interface IOptions {\\n /** Files to revert */\\n files: string[];\\n}\\nexport interface IOptions {\\n /** Branch name to switch to */\\n branch: string;\\n /** Remote name */\\n remote?: string;\\n}\\nexport interface IOptions {\\n /** Tool category to use (fs, npm, git, terminal) */\\n tools: string;\\n /** Function name to invoke */\\n function: string;\\n /** Target directory */\\n target?: string;\\n /** JSON string of parameters */\\n params?: string | undefined;\\n /** Path to write the output to */\\n output?: string | undefined;\\n /** Environment configuration key */\\n env_key?: string | undefined;\\n}\\nexport interface IOptions {\\n /** Path to write the output to */\\n output?: string;\\n}\\nexport interface IOptions {\\n /** Command to execute */\\n command: string;\\n /** Command arguments */\\n args?: string[] | undefined;\\n /** Working directory for command execution */\\n cwd?: string | undefined;\\n /** Run command in background (non-blocking) */\\n background?: boolean | undefined;\\n /** Open command in new terminal window */\\n window?: boolean | undefined;\\n /** Run process detached from parent */\\n detached?: boolean | undefined;\\n}\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\n/** Schema for listing files in a directory */\\nexport const FileListingOptionsSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n});\\n\\n/** Schema for file removal operations */\\nexport const FileRemovalOptionsSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n});\\n\\n/** Schema for git commit operations */\\nexport const GitCommitSchema = z.object({\\n files: z.array(z.string()).describe('Files to commit'),\\n message: z.string().describe('Commit message')\\n});\\n\\n/** Schema for git revert operations */\\nexport const GitRevertSchema = z.object({\\n files: z.array(z.string()).describe('Files to revert')\\n});\\n\\n/** Schema for git version switch operations */\\nexport const GitSwitchVersionSchema = z.object({\\n branch: z.string().describe('Branch name to switch to'),\\n remote: z.string().default('origin').describe('Remote name')\\n});\\n\\n/** Schema for git raw file retrieval */\\nexport const GitRawFileSchema = z.object({\\n url: z.string().optional().describe('Full GitHub raw URL'),\\n repo: z.string().optional().describe('Repository in format owner/repo'),\\n path: z.string().optional().describe('File path within repository')\\n}).refine(\\n data => (data.url) || (data.repo && data.path),\\n 'Either url or both repo and path must be provided'\\n);\\n\\n/** Schema for npm run command */\\nexport const NpmRunSchema = z.object({\\n command: z.string().describe('Command to run (e.g. install, test, etc)'),\\n args: z.array(z.string()).optional().describe('Additional arguments for the command')\\n});\\n\\n/** Schema for terminal command execution */\\nexport const TerminalCommandSchema = z.object({\\n command: z.string().describe('Command to execute'),\\n args: z.array(z.string()).optional().describe('Command arguments'),\\n cwd: z.string().optional().describe('Working directory for command execution'),\\n background: z.boolean().optional().describe('Run command in background (non-blocking)'),\\n window: z.boolean().optional().describe('Open command in new terminal window'),\\n detached: z.boolean().optional().describe('Run process detached from parent')\\n});\\n\\n/** Schema for tool invocation parameters */\\nexport const InvokeToolSchema = z.object({\\n tools: z.string().describe('Tool category to use (fs, npm, git, terminal)'),\\n function: z.string().describe('Function name to invoke'),\\n target: z.string().default(process.cwd()).describe('Target directory'),\\n params: z.string().optional().describe('JSON string of parameters'),\\n output: z.string().optional().describe('Path to write the output to'),\\n env_key: z.string().optional().describe('Environment configuration key')\\n});\\n\\n/** Schema for list command options */\\nexport const ListCommandSchema = z.object({\\n output: z.string().default(\\\"./llm-tools.json\\\").describe('Output file path for tools list')\\n});\\n\\n/** Schema for tool listing options */\\nexport const ToolListingOptionsSchema = z.object({\\n output: z.string().default('./llm-tools.json').describe('Path to write the output to')\\n});\"\n },\n {\n \"path\": \"src\\\\tools.ts\",\n \"content\": \"import { tools as fsTools } from './lib/tools/fs';\\nimport { tools as npmTools } from './lib/tools/npm';\\nimport { tools as gitTools } from './lib/tools/git';\\nimport { tools as terminalTools } from './lib/tools/terminal';\\n\\nexport const tools = {\\n fs: fsTools,\\n npm: npmTools,\\n git: gitTools,\\n terminal: terminalTools\\n};\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport yargs from 'yargs';\\nimport { commands } from './commands';\\nimport { logger } from './';\\n\\nasync function main() {\\n try {\\n const argv = await commands(yargs).argv;\\n } catch (error) {\\n logger.error('Error executing command:', error);\\n process.exit(1);\\n }\\n}\\n\\nmain();\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\terminal.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec, spawn } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'execute_command',\\n description: 'Execute a terminal command and capture output',\\n parameters: {\\n type: 'object',\\n properties: {\\n command: { \\n type: 'string',\\n description: 'Command to execute'\\n },\\n args: {\\n type: 'array',\\n items: { type: 'string' },\\n description: 'Command arguments',\\n optional: true\\n },\\n cwd: {\\n type: 'string',\\n description: 'Working directory for command execution',\\n optional: true\\n },\\n background: {\\n type: 'boolean',\\n description: 'Run command in background (non-blocking)',\\n optional: true\\n },\\n window: {\\n type: 'boolean',\\n description: 'Open command in new terminal window',\\n optional: true\\n },\\n detached: {\\n type: 'boolean',\\n description: 'Run process detached from parent',\\n optional: true\\n }\\n },\\n required: ['command']\\n },\\n function: async (params: any) => {\\n try {\\n const workingDir = params.cwd ? path.join(target, params.cwd) : target;\\n const args = params.args || [];\\n \\n // Handle window mode (platform specific)\\n if (params.window) {\\n const isWindows = process.platform === 'win32';\\n if (isWindows) {\\n spawn('cmd', ['/c', 'start', 'cmd', '/k', params.command, ...args], {\\n cwd: workingDir,\\n detached: true,\\n stdio: 'ignore'\\n });\\n } else {\\n // For macOS/Linux\\n spawn('x-terminal-emulator', ['-e', `${params.command} ${args.join(' ')}`], {\\n cwd: workingDir,\\n detached: true,\\n stdio: 'ignore'\\n });\\n }\\n return {\\n success: true,\\n output: 'Command launched in new window',\\n error: null\\n };\\n }\\n\\n // Handle background/detached mode\\n if (params.background || params.detached) {\\n const child = spawn(params.command, args, {\\n cwd: workingDir,\\n detached: params.detached === true,\\n stdio: 'ignore'\\n });\\n\\n if (params.detached) {\\n child.unref();\\n }\\n\\n return {\\n success: true,\\n output: `Process started with PID: ${child.pid}`,\\n error: null\\n };\\n }\\n\\n // Regular synchronous execution\\n const fullCommand = `${params.command} ${args.join(' ')}`.trim();\\n logger.debug(`Tool::ExecuteCommand Running '${fullCommand}' in ${workingDir}`);\\n const { stdout, stderr } = await execAsync(fullCommand, {\\n cwd: workingDir\\n });\\n\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error: any) {\\n logger.error('Error executing command', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\npm.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'build_project',\\n description: 'Build project using pnpm build command',\\n parameters: {\\n type: 'object',\\n properties: {},\\n required: []\\n },\\n function: async () => {\\n try {\\n logger.debug(`Tool::BuildProject Building project at ${target}`);\\n const { stdout, stderr } = await execAsync('pnpm build', {\\n cwd: target\\n });\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error : any) {\\n logger.error('Error building project', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'run_npm',\\n description: 'Run an npm/pnpm command',\\n parameters: {\\n type: 'object',\\n properties: {\\n command: { type: 'string', description: 'Command to run (e.g. install, test, etc)' },\\n args: { \\n type: 'array',\\n items: { type: 'string' },\\n description: 'Additional arguments for the command',\\n optional: true\\n }\\n },\\n required: ['command']\\n },\\n function: async (params: any) => {\\n try {\\n const args = params.args ? params.args.join(' ') : '';\\n const fullCommand = `pnpm ${params.command} ${args}`.trim();\\n logger.debug(`Tool::RunNpm Running command: ${fullCommand}`);\\n const { stdout, stderr } = await execAsync(fullCommand, {\\n cwd: target\\n });\\n\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error: any) {\\n logger.error('Error running npm command', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\git.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport simpleGit, { SimpleGit } from 'simple-git';\\nimport axios from 'axios';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n const git: SimpleGit = simpleGit(target);\\n\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'commit_files',\\n description: 'Commit files to git repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n files: {\\n type: 'array',\\n items: { type: 'string' }\\n },\\n message: { type: 'string' }\\n },\\n required: ['files', 'message']\\n },\\n function: async (params: any) => {\\n try {\\n logger.debug(`Tool::Git Committing files with message: ${params.message}`);\\n await git.add(params.files);\\n const result = await git.commit(params.message);\\n return {\\n success: true,\\n output: result,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error committing files', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'revert_files',\\n description: 'Revert specified files in git repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n files: {\\n type: 'array',\\n items: { type: 'string' }\\n }\\n },\\n required: ['files']\\n },\\n function: async (params: any) => {\\n try {\\n logger.debug(`Tool::Git Reverting files: ${params.files.join(', ')}`);\\n await git.checkout(['--', ...params.files]);\\n return {\\n success: true,\\n output: 'Files reverted successfully',\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error reverting files', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'switch_version',\\n description: 'Switch to previous version from remote',\\n parameters: {\\n type: 'object',\\n properties: {\\n branch: { type: 'string' },\\n remote: { \\n type: 'string',\\n default: 'origin'\\n }\\n },\\n required: ['branch']\\n },\\n function: async (params: any) => {\\n try {\\n const remote = params.remote || 'origin';\\n logger.debug(`Tool::Git Switching to branch ${params.branch} from ${remote}`);\\n const result = await git.checkout(`${remote}/${params.branch}`);\\n return {\\n success: true,\\n output: result,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error switching version', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'get_raw_file',\\n description: 'Retrieve raw content of a file from GitHub repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n url: { \\n type: 'string',\\n description: 'Full GitHub raw URL or repository path'\\n },\\n repo: {\\n type: 'string',\\n description: 'Repository in format owner/repo'\\n },\\n path: {\\n type: 'string',\\n description: 'File path within repository'\\n }\\n },\\n oneOf: [\\n { required: ['url'] },\\n { required: ['repo', 'path'] }\\n ]\\n },\\n function: async (params: any) => {\\n try {\\n let fileUrl = params.url;\\n if (!fileUrl && params.repo && params.path) {\\n fileUrl = `https://raw.githubusercontent.com/${params.repo}/main/${params.path}`;\\n }\\n \\n logger.debug(`Tool::Git Fetching raw file from ${fileUrl}`);\\n const response = await axios.get(fileUrl);\\n return {\\n success: true,\\n content: response.data,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error fetching raw file', error);\\n return {\\n success: false,\\n content: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { \\n FileListingOptionsSchema, \\n FileRemovalOptionsSchema,\\n GitCommitSchema,\\n GitRevertSchema,\\n GitSwitchVersionSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema,\\n TerminalCommandSchema \\n} from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n FileListingOptionsSchema,\\n FileRemovalOptionsSchema,\\n GitCommitSchema,\\n GitRevertSchema,\\n GitSwitchVersionSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema,\\n TerminalCommandSchema\\n ], 'src/zod_types.ts');\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\list.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { ListCommandSchema } from '../zod_schemas';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport type { Argv } from 'yargs';\\n\\nexport const options = (yargs: Argv) => toYargs(yargs, ListCommandSchema);\\n\\nexport const list = async (argv: any) => {\\n // Initialize tools with current directory\\n const fsTools = tools.fs(process.cwd());\\n const npmTools = tools.npm(process.cwd());\\n const gitTools = tools.git(process.cwd());\\n const terminalTools = tools.terminal(process.cwd());\\n\\n const toolsList = {\\n fs: fsTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'fs'\\n })),\\n npm: npmTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'npm'\\n })),\\n git: gitTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'git'\\n })),\\n terminal: terminalTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'terminal'\\n }))\\n };\\n\\n logger.info('Available Tools:\\\\n');\\n \\n logger.info('Filesystem Tools:');\\n fsTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nNPM Tools:');\\n npmTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nGit Tools:');\\n gitTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nTerminal Tools:');\\n terminalTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n if (argv.output) {\\n logger.info(`\\\\nWriting tools list to ${argv.output}`);\\n write(argv.output, JSON.stringify(toolsList, null, 2));\\n }\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\invoke.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { InvokeToolSchema } from '../zod_schemas';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport type { Argv } from 'yargs';\\nimport * as path from 'path';\\n\\nconst options = (yargs: Argv) => toYargs(yargs, InvokeToolSchema);\\n\\nexport const invoke = async (argv: any) => {\\n try {\\n const { tools: toolCategory, function: funcName, target, params, output } = argv;\\n \\n // Get tool category\\n const toolSet = tools[toolCategory];\\n if (!toolSet) {\\n logger.error(`Tool category '${toolCategory}' not found`);\\n return;\\n }\\n\\n // Initialize tools with target directory\\n const toolList = toolSet(target);\\n \\n // Find specific function\\n const tool = toolList.find(t => t.function.name === funcName);\\n if (!tool) {\\n logger.error(`Function '${funcName}' not found in ${toolCategory} tools`);\\n return;\\n }\\n\\n // Parse parameters if provided\\n const parameters = params ? JSON.parse(params) : {};\\n \\n // Execute tool function\\n logger.info(`Invoking ${toolCategory}::${funcName}`);\\n const result = await tool.function.function(parameters);\\n \\n // Handle output\\n if (output) {\\n const outputPath = path.isAbsolute(output) ? output : path.join(process.cwd(), output);\\n logger.info(`Writing output to ${outputPath}`);\\n write(outputPath, JSON.stringify(result, null, 2));\\n } else {\\n logger.info('Result:', result);\\n }\\n \\n return result;\\n } catch (error) {\\n logger.error('Error invoking tool:', error);\\n throw error;\\n }\\n};\\n\\nexport { options as invokeOptions };\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\nimport { list, options as listOptions } from './list';\\nimport { invoke, invokeOptions } from './invoke';\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons';\\nimport { logger } from '../';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .command('list', 'List all available tools and their descriptions', listOptions, list)\\n .command('invoke', 'Invoke a specific tool function', invokeOptions, invoke)\\n .option('env_key', {\\n type: 'string',\\n description: 'Environment configuration key'\\n })\\n .middleware([(argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any;\\n if (!config) {\\n logger.warn('No config found!');\\n return;\\n }\\n return config;\\n }])\\n .strict()\\n .help();\\n};\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T13:36:46.669Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n### LLM Tools\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { resolve } from \"@plastichub/osr-commons\"\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any, variables:Record={}): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = path.resolve(resolve(join(target, file.path),false,variables))\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : Add names to src/zod_schemas.ts, eg : using .describe('IInvokeSchema')\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\",\\n \\\"list\\\": \\\"ts-node src/main.ts list\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"simple-git\\\": \\\"^3.22.0\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nA command-line interface and library for Language Model tools with filesystem, npm, git, and terminal operations support.\\n\\n## Features\\n\\n- Filesystem operations (list files, remove files)\\n- Git operations (commit, revert, version management)\\n- NPM/PNPM operations (build, run commands)\\n- Terminal command execution (sync/async, background, window modes)\\n- TypeScript interface generation from Zod schemas\\n\\n## Prerequisites\\n\\n- Node.js >= 16\\n- pnpm (recommended) or npm\\n- Git (for git operations)\\n\\n## Installation\\n\\n```bash\\n# Clone the repository\\ngit clone \\ncd llm-tools-cli\\n\\n# Install dependencies\\npnpm install\\n\\n# Build the project\\npnpm build\\n```\\n\\n## Environment Configuration\\n\\nThe CLI supports configuration via environment files or variables:\\n\\n1. Create a `.env` file or set environment variables:\\n ```env\\n OPENAI_API_KEY=your-api-key-here\\n ```\\n\\n2. Or use config files with `--env_key`:\\n ```bash\\n llm-tools invoke --env_key=production ...\\n ```\\n\\n## Command Line Usage\\n\\n### List Available Tools\\n\\nList all available tools and their descriptions:\\n\\n```bash\\npnpm list [--output=./llm-tools.json]\\n```\\n\\n### Generate TypeScript Types\\n\\nGenerates TypeScript interfaces from Zod schemas:\\n\\n```bash\\npnpm types\\n```\\n\\n### Invoke Tool\\n\\nInvoke a specific tool function:\\n\\n```bash\\npnpm invoke --tools= --function= [options]\\n\\nOptions:\\n --tools Tool category (fs, npm, git, terminal)\\n --function Function name to invoke\\n --target Target directory [default: current]\\n --params JSON string of parameters\\n --output Output file path\\n --env_key Environment key\\n```\\n\\n## Available Tools\\n\\n### Filesystem Tools\\n\\n```typescript\\n// List files in directory\\nawait invoke({\\n tools: 'fs',\\n function: 'list_files',\\n params: JSON.stringify({\\n directory: 'src',\\n pattern: '**/*.ts'\\n })\\n})\\n\\n// Remove file\\nawait invoke({\\n tools: 'fs',\\n function: 'remove_file',\\n params: JSON.stringify({\\n path: 'temp.txt'\\n })\\n})\\n```\\n\\n### Git Tools\\n\\n```typescript\\n// Commit files\\nawait invoke({\\n tools: 'git',\\n function: 'commit_files',\\n params: JSON.stringify({\\n files: ['src/main.ts'],\\n message: 'Update code'\\n })\\n})\\n\\n// Revert files\\nawait invoke({\\n tools: 'git',\\n function: 'revert_files',\\n params: JSON.stringify({\\n files: ['src/config.ts']\\n })\\n})\\n\\n// Switch version\\nawait invoke({\\n tools: 'git',\\n function: 'switch_version',\\n params: JSON.stringify({\\n branch: 'main',\\n remote: 'origin'\\n })\\n})\\n\\n// Get raw file from GitHub\\nawait invoke({\\n tools: 'git',\\n function: 'get_raw_file',\\n params: JSON.stringify({\\n repo: 'owner/repo',\\n path: 'path/to/file.ts'\\n })\\n})\\n```\\n\\n### NPM Tools\\n\\n```typescript\\n// Build project\\nawait invoke({\\n tools: 'npm',\\n function: 'build_project'\\n})\\n\\n// Run npm command\\nawait invoke({\\n tools: 'npm',\\n function: 'run_npm',\\n params: JSON.stringify({\\n command: 'install',\\n args: ['--save-dev', 'typescript']\\n })\\n})\\n```\\n\\n### Terminal Tools\\n\\n```typescript\\n// Execute command synchronously\\nawait invoke({\\n tools: 'terminal',\\n function: 'execute_command',\\n params: JSON.stringify({\\n command: 'ls',\\n args: ['-la'],\\n cwd: 'src'\\n })\\n})\\n\\n// Run in background\\nawait invoke({\\n tools: 'terminal',\\n function: 'execute_command',\\n params: JSON.stringify({\\n command: 'npm',\\n args: ['start'],\\n background: true\\n })\\n})\\n\\n// Open in new window\\nawait invoke({\\n tools: 'terminal',\\n function: 'execute_command',\\n params: JSON.stringify({\\n command: 'vim',\\n args: ['file.txt'],\\n window: true\\n })\\n})\\n```\\n\\n## Using as a Library\\n\\n### Setting up Logger\\n\\n```typescript\\nimport { Logger } from 'tslog'\\nimport { createLogger } from '@plastichub/osr-log'\\n\\nexport const logger: Logger = createLogger('package-name')\\n```\\n\\n### Type-safe CLI Arguments\\n\\n```typescript\\nimport { z } from 'zod'\\nimport { toYargs } from '@plastichub/osr-commons'\\nimport type { Argv } from 'yargs'\\n\\nconst MySchema = z.object({\\n directory: z.string().describe('Directory path')\\n})\\n\\nconst options = (yargs: Argv) => toYargs(yargs, MySchema)\\n```\\n\\n### Configuration Management\\n\\n```typescript\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\\n\\nexport const example = (argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any\\n if (!config) {\\n logger.warn('No config found!')\\n return\\n }\\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\\n}\\n```\\n\\n### Using Custom Filesystem Operations\\n\\n```typescript\\nimport { sync as rm } from '@plastichub/fs/remove'\\nimport { sync as dir } from '@plastichub/fs/dir'\\nimport { sync as write } from '@plastichub/fs/write'\\nimport { sync as read } from '@plastichub/fs/read'\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob'\\n\\n// Create directory\\ndir('path/to/dir')\\n\\n// Write file\\nwrite('file.txt', 'content')\\n\\n// Read file\\nconst content = read('file.txt')\\n\\n// Remove file\\nrm('file.txt')\\n\\n// List files\\nconst files = glob('src', ['**/*.ts'])\\n```\\n\\n## Contributing\\n\\n1. Fork the repository\\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\\n3. Commit changes (`git commit -m 'Add amazing feature'`)\\n4. Push to branch (`git push origin feature/amazing-feature`)\\n5. Open a Pull Request\\n\\n## License\\n\\nThis project is licensed under the MIT License.\\n\"\n },\n {\n \"path\": \"src\\\\zod_types.ts\",\n \"content\": \"export interface IOptions {\\n /** Directory path to list files from */\\n directory: string;\\n /** Glob pattern for filtering files */\\n pattern?: string | undefined;\\n}\\nexport interface IOptions {\\n /** Path of the file to remove */\\n path: string;\\n}\\nexport interface IOptions {\\n /** Files to commit */\\n files: string[];\\n /** Commit message */\\n message: string;\\n}\\nexport interface IOptions {\\n /** Files to revert */\\n files: string[];\\n}\\nexport interface IOptions {\\n /** Branch name to switch to */\\n branch: string;\\n /** Remote name */\\n remote?: string;\\n}\\nexport interface IOptions {\\n /** Tool category to use (fs, npm, git, terminal) */\\n tools: string;\\n /** Function name to invoke */\\n function: string;\\n /** Target directory */\\n target?: string;\\n /** JSON string of parameters */\\n params?: string | undefined;\\n /** Path to write the output to */\\n output?: string | undefined;\\n /** Environment configuration key */\\n env_key?: string | undefined;\\n}\\nexport interface IOptions {\\n /** Path to write the output to */\\n output?: string;\\n}\\nexport interface IOptions {\\n /** Command to execute */\\n command: string;\\n /** Command arguments */\\n args?: string[] | undefined;\\n /** Working directory for command execution */\\n cwd?: string | undefined;\\n /** Run command in background (non-blocking) */\\n background?: boolean | undefined;\\n /** Open command in new terminal window */\\n window?: boolean | undefined;\\n /** Run process detached from parent */\\n detached?: boolean | undefined;\\n}\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\n/** Schema for listing files in a directory */\\nexport const FileListingOptionsSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n});\\n\\n/** Schema for file removal operations */\\nexport const FileRemovalOptionsSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n});\\n\\n/** Schema for git commit operations */\\nexport const GitCommitSchema = z.object({\\n files: z.array(z.string()).describe('Files to commit'),\\n message: z.string().describe('Commit message')\\n});\\n\\n/** Schema for git revert operations */\\nexport const GitRevertSchema = z.object({\\n files: z.array(z.string()).describe('Files to revert')\\n});\\n\\n/** Schema for git version switch operations */\\nexport const GitSwitchVersionSchema = z.object({\\n branch: z.string().describe('Branch name to switch to'),\\n remote: z.string().default('origin').describe('Remote name')\\n});\\n\\n/** Schema for git raw file retrieval */\\nexport const GitRawFileSchema = z.object({\\n url: z.string().optional().describe('Full GitHub raw URL'),\\n repo: z.string().optional().describe('Repository in format owner/repo'),\\n path: z.string().optional().describe('File path within repository')\\n}).refine(\\n data => (data.url) || (data.repo && data.path),\\n 'Either url or both repo and path must be provided'\\n);\\n\\n/** Schema for npm run command */\\nexport const NpmRunSchema = z.object({\\n command: z.string().describe('Command to run (e.g. install, test, etc)'),\\n args: z.array(z.string()).optional().describe('Additional arguments for the command')\\n});\\n\\n/** Schema for terminal command execution */\\nexport const TerminalCommandSchema = z.object({\\n command: z.string().describe('Command to execute'),\\n args: z.array(z.string()).optional().describe('Command arguments'),\\n cwd: z.string().optional().describe('Working directory for command execution'),\\n background: z.boolean().optional().describe('Run command in background (non-blocking)'),\\n window: z.boolean().optional().describe('Open command in new terminal window'),\\n detached: z.boolean().optional().describe('Run process detached from parent')\\n});\\n\\n/** Schema for tool invocation parameters */\\nexport const InvokeToolSchema = z.object({\\n tools: z.string().describe('Tool category to use (fs, npm, git, terminal)'),\\n function: z.string().describe('Function name to invoke'),\\n target: z.string().default(process.cwd()).describe('Target directory'),\\n params: z.string().optional().describe('JSON string of parameters'),\\n output: z.string().optional().describe('Path to write the output to'),\\n env_key: z.string().optional().describe('Environment configuration key')\\n});\\n\\n/** Schema for list command options */\\nexport const ListCommandSchema = z.object({\\n output: z.string().default(\\\"./llm-tools.json\\\").describe('Output file path for tools list')\\n});\\n\\n/** Schema for tool listing options */\\nexport const ToolListingOptionsSchema = z.object({\\n output: z.string().default('./llm-tools.json').describe('Path to write the output to')\\n});\"\n },\n {\n \"path\": \"src\\\\tools.ts\",\n \"content\": \"import { tools as fsTools } from './lib/tools/fs';\\nimport { tools as npmTools } from './lib/tools/npm';\\nimport { tools as gitTools } from './lib/tools/git';\\nimport { tools as terminalTools } from './lib/tools/terminal';\\n\\nexport const tools = {\\n fs: fsTools,\\n npm: npmTools,\\n git: gitTools,\\n terminal: terminalTools\\n};\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport yargs from 'yargs';\\nimport { commands } from './commands';\\nimport { logger } from './';\\n\\nasync function main() {\\n try {\\n const argv = await commands(yargs).argv;\\n } catch (error) {\\n logger.error('Error executing command:', error);\\n process.exit(1);\\n }\\n}\\n\\nmain();\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\terminal.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec, spawn } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'execute_command',\\n description: 'Execute a terminal command and capture output',\\n parameters: {\\n type: 'object',\\n properties: {\\n command: { \\n type: 'string',\\n description: 'Command to execute'\\n },\\n args: {\\n type: 'array',\\n items: { type: 'string' },\\n description: 'Command arguments',\\n optional: true\\n },\\n cwd: {\\n type: 'string',\\n description: 'Working directory for command execution',\\n optional: true\\n },\\n background: {\\n type: 'boolean',\\n description: 'Run command in background (non-blocking)',\\n optional: true\\n },\\n window: {\\n type: 'boolean',\\n description: 'Open command in new terminal window',\\n optional: true\\n },\\n detached: {\\n type: 'boolean',\\n description: 'Run process detached from parent',\\n optional: true\\n }\\n },\\n required: ['command']\\n },\\n function: async (params: any) => {\\n try {\\n const workingDir = params.cwd ? path.join(target, params.cwd) : target;\\n const args = params.args || [];\\n \\n // Handle window mode (platform specific)\\n if (params.window) {\\n const isWindows = process.platform === 'win32';\\n if (isWindows) {\\n spawn('cmd', ['/c', 'start', 'cmd', '/k', params.command, ...args], {\\n cwd: workingDir,\\n detached: true,\\n stdio: 'ignore'\\n });\\n } else {\\n // For macOS/Linux\\n spawn('x-terminal-emulator', ['-e', `${params.command} ${args.join(' ')}`], {\\n cwd: workingDir,\\n detached: true,\\n stdio: 'ignore'\\n });\\n }\\n return {\\n success: true,\\n output: 'Command launched in new window',\\n error: null\\n };\\n }\\n\\n // Handle background/detached mode\\n if (params.background || params.detached) {\\n const child = spawn(params.command, args, {\\n cwd: workingDir,\\n detached: params.detached === true,\\n stdio: 'ignore'\\n });\\n\\n if (params.detached) {\\n child.unref();\\n }\\n\\n return {\\n success: true,\\n output: `Process started with PID: ${child.pid}`,\\n error: null\\n };\\n }\\n\\n // Regular synchronous execution\\n const fullCommand = `${params.command} ${args.join(' ')}`.trim();\\n logger.debug(`Tool::ExecuteCommand Running '${fullCommand}' in ${workingDir}`);\\n const { stdout, stderr } = await execAsync(fullCommand, {\\n cwd: workingDir\\n });\\n\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error: any) {\\n logger.error('Error executing command', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\npm.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'build_project',\\n description: 'Build project using pnpm build command',\\n parameters: {\\n type: 'object',\\n properties: {},\\n required: []\\n },\\n function: async () => {\\n try {\\n logger.debug(`Tool::BuildProject Building project at ${target}`);\\n const { stdout, stderr } = await execAsync('pnpm build', {\\n cwd: target\\n });\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error : any) {\\n logger.error('Error building project', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'run_npm',\\n description: 'Run an npm/pnpm command',\\n parameters: {\\n type: 'object',\\n properties: {\\n command: { type: 'string', description: 'Command to run (e.g. install, test, etc)' },\\n args: { \\n type: 'array',\\n items: { type: 'string' },\\n description: 'Additional arguments for the command',\\n optional: true\\n }\\n },\\n required: ['command']\\n },\\n function: async (params: any) => {\\n try {\\n const args = params.args ? params.args.join(' ') : '';\\n const fullCommand = `pnpm ${params.command} ${args}`.trim();\\n logger.debug(`Tool::RunNpm Running command: ${fullCommand}`);\\n const { stdout, stderr } = await execAsync(fullCommand, {\\n cwd: target\\n });\\n\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error: any) {\\n logger.error('Error running npm command', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\git.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport simpleGit, { SimpleGit } from 'simple-git';\\nimport axios from 'axios';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n const git: SimpleGit = simpleGit(target);\\n\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'commit_files',\\n description: 'Commit files to git repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n files: {\\n type: 'array',\\n items: { type: 'string' }\\n },\\n message: { type: 'string' }\\n },\\n required: ['files', 'message']\\n },\\n function: async (params: any) => {\\n try {\\n logger.debug(`Tool::Git Committing files with message: ${params.message}`);\\n await git.add(params.files);\\n const result = await git.commit(params.message);\\n return {\\n success: true,\\n output: result,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error committing files', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'revert_files',\\n description: 'Revert specified files in git repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n files: {\\n type: 'array',\\n items: { type: 'string' }\\n }\\n },\\n required: ['files']\\n },\\n function: async (params: any) => {\\n try {\\n logger.debug(`Tool::Git Reverting files: ${params.files.join(', ')}`);\\n await git.checkout(['--', ...params.files]);\\n return {\\n success: true,\\n output: 'Files reverted successfully',\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error reverting files', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'switch_version',\\n description: 'Switch to previous version from remote',\\n parameters: {\\n type: 'object',\\n properties: {\\n branch: { type: 'string' },\\n remote: { \\n type: 'string',\\n default: 'origin'\\n }\\n },\\n required: ['branch']\\n },\\n function: async (params: any) => {\\n try {\\n const remote = params.remote || 'origin';\\n logger.debug(`Tool::Git Switching to branch ${params.branch} from ${remote}`);\\n const result = await git.checkout(`${remote}/${params.branch}`);\\n return {\\n success: true,\\n output: result,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error switching version', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'get_raw_file',\\n description: 'Retrieve raw content of a file from GitHub repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n url: { \\n type: 'string',\\n description: 'Full GitHub raw URL or repository path'\\n },\\n repo: {\\n type: 'string',\\n description: 'Repository in format owner/repo'\\n },\\n path: {\\n type: 'string',\\n description: 'File path within repository'\\n }\\n },\\n oneOf: [\\n { required: ['url'] },\\n { required: ['repo', 'path'] }\\n ]\\n },\\n function: async (params: any) => {\\n try {\\n let fileUrl = params.url;\\n if (!fileUrl && params.repo && params.path) {\\n fileUrl = `https://raw.githubusercontent.com/${params.repo}/main/${params.path}`;\\n }\\n \\n logger.debug(`Tool::Git Fetching raw file from ${fileUrl}`);\\n const response = await axios.get(fileUrl);\\n return {\\n success: true,\\n content: response.data,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error fetching raw file', error);\\n return {\\n success: false,\\n content: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { \\n FileListingOptionsSchema, \\n FileRemovalOptionsSchema,\\n GitCommitSchema,\\n GitRevertSchema,\\n GitSwitchVersionSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema,\\n TerminalCommandSchema \\n} from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n FileListingOptionsSchema,\\n FileRemovalOptionsSchema,\\n GitCommitSchema,\\n GitRevertSchema,\\n GitSwitchVersionSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema,\\n TerminalCommandSchema\\n ], 'src/zod_types.ts');\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\list.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { ListCommandSchema } from '../zod_schemas';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport type { Argv } from 'yargs';\\n\\nexport const options = (yargs: Argv) => toYargs(yargs, ListCommandSchema);\\n\\nexport const list = async (argv: any) => {\\n // Initialize tools with current directory\\n const fsTools = tools.fs(process.cwd());\\n const npmTools = tools.npm(process.cwd());\\n const gitTools = tools.git(process.cwd());\\n const terminalTools = tools.terminal(process.cwd());\\n\\n const toolsList = {\\n fs: fsTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'fs'\\n })),\\n npm: npmTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'npm'\\n })),\\n git: gitTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'git'\\n })),\\n terminal: terminalTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'terminal'\\n }))\\n };\\n\\n logger.info('Available Tools:\\\\n');\\n \\n logger.info('Filesystem Tools:');\\n fsTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nNPM Tools:');\\n npmTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nGit Tools:');\\n gitTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nTerminal Tools:');\\n terminalTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n if (argv.output) {\\n logger.info(`\\\\nWriting tools list to ${argv.output}`);\\n write(argv.output, JSON.stringify(toolsList, null, 2));\\n }\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\invoke.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { InvokeToolSchema } from '../zod_schemas';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport type { Argv } from 'yargs';\\nimport * as path from 'path';\\n\\nconst options = (yargs: Argv) => toYargs(yargs, InvokeToolSchema);\\n\\nexport const invoke = async (argv: any) => {\\n try {\\n const { tools: toolCategory, function: funcName, target, params, output } = argv;\\n \\n // Get tool category\\n const toolSet = tools[toolCategory];\\n if (!toolSet) {\\n logger.error(`Tool category '${toolCategory}' not found`);\\n return;\\n }\\n\\n // Initialize tools with target directory\\n const toolList = toolSet(target);\\n \\n // Find specific function\\n const tool = toolList.find(t => t.function.name === funcName);\\n if (!tool) {\\n logger.error(`Function '${funcName}' not found in ${toolCategory} tools`);\\n return;\\n }\\n\\n // Parse parameters if provided\\n const parameters = params ? JSON.parse(params) : {};\\n \\n // Execute tool function\\n logger.info(`Invoking ${toolCategory}::${funcName}`);\\n const result = await tool.function.function(parameters);\\n \\n // Handle output\\n if (output) {\\n const outputPath = path.isAbsolute(output) ? output : path.join(process.cwd(), output);\\n logger.info(`Writing output to ${outputPath}`);\\n write(outputPath, JSON.stringify(result, null, 2));\\n } else {\\n logger.info('Result:', result);\\n }\\n \\n return result;\\n } catch (error) {\\n logger.error('Error invoking tool:', error);\\n throw error;\\n }\\n};\\n\\nexport { options as invokeOptions };\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\nimport { list, options as listOptions } from './list';\\nimport { invoke, invokeOptions } from './invoke';\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons';\\nimport { logger } from '../';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .command('list', 'List all available tools and their descriptions', listOptions, list)\\n .command('invoke', 'Invoke a specific tool function', invokeOptions, invoke)\\n .option('env_key', {\\n type: 'string',\\n description: 'Environment configuration key'\\n })\\n .middleware([(argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any;\\n if (!config) {\\n logger.warn('No config found!');\\n return;\\n }\\n return config;\\n }])\\n .strict()\\n .help();\\n};\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T13:38:09.018Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n### LLM Tools\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { resolve } from \"@plastichub/osr-commons\"\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any, variables:Record={}): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = path.resolve(resolve(join(target, file.path),false,variables))\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : Add names to src/zod_schemas.ts, eg : using .describe('IInvokeSchema')\n\nCurrent files:\n[\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\n/** Schema for listing files in a directory */\\nexport const FileListingOptionsSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n}).describe('IFileListingOptions');\\n\\n/** Schema for file removal operations */\\nexport const FileRemovalOptionsSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n}).describe('IFileRemovalOptions');\\n\\n/** Schema for git commit operations */\\nexport const GitCommitSchema = z.object({\\n files: z.array(z.string()).describe('Files to commit'),\\n message: z.string().describe('Commit message')\\n}).describe('IGitCommitOptions');\\n\\n/** Schema for git revert operations */\\nexport const GitRevertSchema = z.object({\\n files: z.array(z.string()).describe('Files to revert')\\n}).describe('IGitRevertOptions');\\n\\n/** Schema for git version switch operations */\\nexport const GitSwitchVersionSchema = z.object({\\n branch: z.string().describe('Branch name to switch to'),\\n remote: z.string().default('origin').describe('Remote name')\\n}).describe('IGitSwitchVersionOptions');\\n\\n/** Schema for git raw file retrieval */\\nexport const GitRawFileSchema = z.object({\\n url: z.string().optional().describe('Full GitHub raw URL'),\\n repo: z.string().optional().describe('Repository in format owner/repo'),\\n path: z.string().optional().describe('File path within repository')\\n}).refine(\\n data => (data.url) || (data.repo && data.path),\\n 'Either url or both repo and path must be provided'\\n).describe('IGitRawFileOptions');\\n\\n/** Schema for npm run command */\\nexport const NpmRunSchema = z.object({\\n command: z.string().describe('Command to run (e.g. install, test, etc)'),\\n args: z.array(z.string()).optional().describe('Additional arguments for the command')\\n}).describe('INpmRunOptions');\\n\\n/** Schema for terminal command execution */\\nexport const TerminalCommandSchema = z.object({\\n command: z.string().describe('Command to execute'),\\n args: z.array(z.string()).optional().describe('Command arguments'),\\n cwd: z.string().optional().describe('Working directory for command execution'),\\n background: z.boolean().optional().describe('Run command in background (non-blocking)'),\\n window: z.boolean().optional().describe('Open command in new terminal window'),\\n detached: z.boolean().optional().describe('Run process detached from parent')\\n}).describe('ITerminalCommandOptions');\\n\\n/** Schema for tool invocation parameters */\\nexport const InvokeToolSchema = z.object({\\n tools: z.string().describe('Tool category to use (fs, npm, git, terminal)'),\\n function: z.string().describe('Function name to invoke'),\\n target: z.string().default(process.cwd()).describe('Target directory'),\\n params: z.string().optional().describe('JSON string of parameters'),\\n output: z.string().optional().describe('Path to write the output to'),\\n env_key: z.string().optional().describe('Environment configuration key')\\n}).describe('IInvokeToolOptions');\\n\\n/** Schema for list command options */\\nexport const ListCommandSchema = z.object({\\n output: z.string().default(\\\"./llm-tools.json\\\").describe('Output file path for tools list')\\n}).describe('IListCommandOptions');\\n\\n/** Schema for tool listing options */\\nexport const ToolListingOptionsSchema = z.object({\\n output: z.string().default('./llm-tools.json').describe('Path to write the output to')\\n}).describe('IToolListingOptions');\"\n },\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\",\\n \\\"list\\\": \\\"ts-node src/main.ts list\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"simple-git\\\": \\\"^3.22.0\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nA command-line interface and library for Language Model tools with filesystem, npm, git, and terminal operations support.\\n\\n## Architecture\\n\\nThe project follows a clean architecture with clear separation of concerns:\\n\\n```\\nsrc/\\n ├── commands/ # CLI commands implementation\\n ├── lib/ # Core functionality and tools\\n │ └── tools/ # Tool implementations (fs, git, npm, terminal)\\n ├── constants.ts # Global constants\\n ├── index.ts # Logger initialization\\n ├── main.ts # CLI entry point\\n ├── tools.ts # Tool registration\\n ├── zod_schemas.ts # Zod schemas for validation\\n └── zod_types.ts # Generated TypeScript interfaces\\n```\\n\\n## Installation\\n\\n```bash\\n# Using pnpm (recommended)\\npnpm install\\n\\n# Or using npm\\nnpm install\\n\\n# Build the project\\npnpm build\\n```\\n\\n## CLI Commands\\n\\n### Generate TypeScript Types\\n\\nGenerate TypeScript interfaces from Zod schemas:\\n\\n```bash\\npnpm types\\n```\\n\\n### List Available Tools\\n\\nDisplay all available tools and their descriptions:\\n\\n```bash\\npnpm list [--output=./llm-tools.json]\\n```\\n\\n### Invoke Tool\\n\\nExecute a specific tool function:\\n\\n```bash\\npnpm invoke --tools= --function= [options]\\n\\nOptions:\\n --tools Tool category (fs, npm, git, terminal)\\n --function Function name to invoke\\n --target Target directory [default: current]\\n --params JSON string of parameters\\n --output Output file path\\n --env_key Environment key\\n```\\n\\n## Library Usage\\n\\n### Logger Setup\\n\\n```typescript\\nimport { Logger } from 'tslog'\\nimport { createLogger } from '@plastichub/osr-log'\\n\\nexport const logger: Logger = createLogger('package-name')\\n```\\n\\n### Configuration\\n\\n```typescript\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\\n\\nexport const example = (argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any\\n if (!config) {\\n logger.warn('No config found!')\\n return\\n }\\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\\n}\\n```\\n\\n### Filesystem Operations\\n\\n```typescript\\nimport { sync as rm } from '@plastichub/fs/remove'\\nimport { sync as dir } from '@plastichub/fs/dir'\\nimport { sync as write } from '@plastichub/fs/write'\\nimport { sync as read } from '@plastichub/fs/read'\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob'\\n\\n// Create directory\\ndir('path/to/dir')\\n\\n// Write file\\nwrite('file.txt', 'content')\\n\\n// Read file\\nconst content = read('file.txt')\\n\\n// Remove file\\nrm('file.txt')\\n\\n// List files\\nconst files = glob('src', ['**/*.ts'])\\n```\\n\\n### Tool Implementation\\n\\nExample tool implementation:\\n\\n```typescript\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\\nimport { logger } from '../../index'\\n\\nexport const tools = (target: string): Array => [\\n {\\n type: 'function',\\n function: {\\n name: 'example_tool',\\n description: 'Example tool description',\\n parameters: {\\n type: 'object',\\n properties: {\\n param: { type: 'string' }\\n },\\n required: ['param']\\n },\\n function: async (params: any) => {\\n try {\\n logger.debug(`Tool::ExampleTool executing with params:`, params)\\n // Tool implementation\\n return { success: true }\\n } catch (error) {\\n logger.error('Error in example tool', error)\\n throw error\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n]\\n```\\n\\n### Yargs Command Registration\\n\\n```typescript\\nimport type { Argv } from 'yargs'\\nimport { toYargs } from '@plastichub/osr-commons'\\nimport { ExampleSchema } from '../zod_schemas'\\n\\n// Command options\\nexport const options = (yargs: Argv) => toYargs(yargs, ExampleSchema)\\n\\n// Command implementation\\nexport const command = async (argv: any) => {\\n // Command logic\\n}\\n\\n// Register in src/commands/index.ts\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('example', 'Example command', options, command)\\n .strict()\\n .help()\\n}\\n```\\n\\n### Zod Schema Definition\\n\\n```typescript\\nimport { z } from 'zod'\\n\\nexport const ExampleSchema = z.object({\\n param: z.string().describe('Parameter description')\\n}).describe('IExampleOptions')\\n```\\n\\n## Development\\n\\n1. Add new tool functionality in `src/lib/tools/`\\n2. Define Zod schemas in `src/zod_schemas.ts`\\n3. Register tool functions in `src/tools.ts`\\n4. Add CLI commands in `src/commands/`\\n5. Register commands in `src/commands/index.ts`\\n6. Generate types: `pnpm types`\\n\\n## Environment Variables\\n\\n```env\\nOPENAI_API_KEY=your-api-key-here\\n```\\n\\nOr use config files with `--env_key`:\\n```bash\\nllm-tools invoke --env_key=production ...\\n```\\n\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T13:39:34.902Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n### LLM Tools\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { resolve } from \"@plastichub/osr-commons\"\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any, variables:Record={}): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = path.resolve(resolve(join(target, file.path),false,variables))\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : Name all zod schemas in src/zod_schemas.ts, eg: using Schema.describe('IInvokeSchema')\n\nCurrent files:\n[\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\n/** Schema for listing files in a directory */\\nexport const FileListingOptionsSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n}).describe('IFileListingOptions');\\n\\n/** Schema for file removal operations */\\nexport const FileRemovalOptionsSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n}).describe('IFileRemovalOptions');\\n\\n/** Schema for git commit operations */\\nexport const GitCommitSchema = z.object({\\n files: z.array(z.string()).describe('Files to commit'),\\n message: z.string().describe('Commit message')\\n}).describe('IGitCommitOptions');\\n\\n/** Schema for git revert operations */\\nexport const GitRevertSchema = z.object({\\n files: z.array(z.string()).describe('Files to revert')\\n}).describe('IGitRevertOptions');\\n\\n/** Schema for git version switch operations */\\nexport const GitSwitchVersionSchema = z.object({\\n branch: z.string().describe('Branch name to switch to'),\\n remote: z.string().default('origin').describe('Remote name')\\n}).describe('IGitSwitchVersionOptions');\\n\\n/** Schema for git raw file retrieval */\\nexport const GitRawFileSchema = z.object({\\n url: z.string().optional().describe('Full GitHub raw URL'),\\n repo: z.string().optional().describe('Repository in format owner/repo'),\\n path: z.string().optional().describe('File path within repository')\\n}).refine(\\n data => (data.url) || (data.repo && data.path),\\n 'Either url or both repo and path must be provided'\\n).describe('IGitRawFileOptions');\\n\\n/** Schema for npm run command */\\nexport const NpmRunSchema = z.object({\\n command: z.string().describe('Command to run (e.g. install, test, etc)'),\\n args: z.array(z.string()).optional().describe('Additional arguments for the command')\\n}).describe('INpmRunOptions');\\n\\n/** Schema for terminal command execution */\\nexport const TerminalCommandSchema = z.object({\\n command: z.string().describe('Command to execute'),\\n args: z.array(z.string()).optional().describe('Command arguments'),\\n cwd: z.string().optional().describe('Working directory for command execution'),\\n background: z.boolean().optional().describe('Run command in background (non-blocking)'),\\n window: z.boolean().optional().describe('Open command in new terminal window'),\\n detached: z.boolean().optional().describe('Run process detached from parent')\\n}).describe('ITerminalCommandOptions');\\n\\n/** Schema for tool invocation parameters */\\nexport const InvokeToolSchema = z.object({\\n tools: z.string().describe('Tool category to use (fs, npm, git, terminal)'),\\n function: z.string().describe('Function name to invoke'),\\n target: z.string().default(process.cwd()).describe('Target directory'),\\n params: z.string().optional().describe('JSON string of parameters'),\\n output: z.string().optional().describe('Path to write the output to'),\\n env_key: z.string().optional().describe('Environment configuration key')\\n}).describe('IInvokeToolOptions');\\n\\n/** Schema for list command options */\\nexport const ListCommandSchema = z.object({\\n output: z.string().default(\\\"./llm-tools.json\\\").describe('Output file path for tools list')\\n}).describe('IListCommandOptions');\\n\\n/** Schema for tool listing options */\\nexport const ToolListingOptionsSchema = z.object({\\n output: z.string().default('./llm-tools.json').describe('Path to write the output to')\\n}).describe('IToolListingOptions');\"\n },\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\",\\n \\\"list\\\": \\\"ts-node src/main.ts list\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"simple-git\\\": \\\"^3.22.0\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nCommand-line interface for LLM tools providing filesystem, npm, git, and terminal operations.\\n\\n## Setup\\n\\n1. Clone the repository\\n2. Install dependencies:\\n```bash\\npnpm install\\n```\\n\\n3. Build the project:\\n```bash\\npnpm build\\n```\\n\\n4. Configure environment:\\nEither set environment variable:\\n```bash\\nexport OPENAI_API_KEY=your-key-here\\n```\\nOr use config file with --env_key parameter\\n\\n## Available Commands\\n\\n### Generate Types\\nGenerates TypeScript interfaces from Zod schemas:\\n```bash\\npnpm types\\n```\\n\\n### List Files\\nList files in a directory:\\n```bash\\npnpm start files --directory ./src --pattern \\\"**/*.ts\\\"\\n```\\n\\n### Remove Files\\nRemove files:\\n```bash\\npnpm start remove --path ./temp.txt\\n```\\n\\n### Git Operations\\n\\n#### Commit\\n```bash\\npnpm start git commit --files [\\\"file1\\\",\\\"file2\\\"] --message \\\"commit message\\\"\\n```\\n\\n#### Revert\\n```bash\\npnpm start git revert --files [\\\"file1\\\",\\\"file2\\\"]\\n```\\n\\n#### Switch Version\\n```bash\\npnpm start git switch --branch main --remote origin\\n```\\n\\n#### Get Raw File\\n```bash\\npnpm start git raw --url \\\"https://raw...\\\" \\n# or\\npnpm start git raw --repo \\\"owner/repo\\\" --path \\\"path/to/file\\\"\\n```\\n\\n### NPM Commands\\n```bash\\npnpm start npm run --command install --args [\\\"-D\\\",\\\"typescript\\\"]\\n```\\n\\n### Terminal Commands\\n```bash\\npnpm start terminal exec --command \\\"echo\\\" --args [\\\"hello\\\"] --cwd \\\"./\\\"\\n```\\n\\n## Library Usage\\n\\n### Logger Setup\\n```typescript\\nimport { Logger } from 'tslog'\\nimport { createLogger } from '@plastichub/osr-log'\\n\\nexport const logger: Logger = createLogger('package-name')\\n```\\n\\n### Configuration Access\\n```typescript\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\\n\\nconst config = CONFIG_DEFAULT('env_key')\\nconst api_key = process.env.OPENAI_API_KEY || config?.openai?.key\\n```\\n\\n### File Operations\\n```typescript\\nimport { sync as rm } from '@plastichub/fs/remove'\\nimport { sync as dir } from '@plastichub/fs/dir'\\nimport { sync as write } from '@plastichub/fs/write'\\nimport { sync as read } from '@plastichub/fs/read'\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob'\\n\\n// Directory operations\\ndir('path/to/dir')\\n\\n// File operations\\nwrite('file.txt', 'content')\\nconst content = read('file.txt')\\nrm('file.txt')\\n\\n// Glob patterns\\nconst files = glob('src', ['**/*.ts'])\\n```\\n\\n### Zod Schema Integration\\n```typescript\\nimport { toYargs } from '@plastichub/osr-commons'\\nimport { MySchema } from './schemas'\\n\\n// Convert schema to Yargs options\\nconst options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\\n```\\n\\n### Generate TypeScript Interfaces\\n```typescript\\nimport { generate_interfaces } from '@plastichub/osr-commons'\\nimport { MySchema } from './schemas'\\n\\nexport const types = () => generate_interfaces(\\n [MySchema()],\\n 'src/zod_types.ts'\\n)\\n```\\n\\n## Development\\n\\n1. Add new tool in src/lib/tools/\\n2. Define schemas in src/zod_schemas.ts\\n3. Implement command in src/commands/\\n4. Register command in src/commands/index.ts\\n5. Run `pnpm types` to update TypeScript interfaces\\n\\n## Project Structure\\n```\\nsrc/\\n ├── commands/ # CLI command implementations\\n ├── lib/ # Core functionality \\n │ └── tools/ # Tool implementations\\n ├── constants.ts # Global constants\\n ├── index.ts # Logger setup\\n ├── main.ts # CLI entry point\\n ├── zod_schemas.ts # Zod schemas\\n └── zod_types.ts # Generated interfaces\\n```\\n\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T13:41:01.658Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n### LLM Tools\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { resolve } from \"@plastichub/osr-commons\"\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any, variables:Record={}): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = path.resolve(resolve(join(target, file.path),false,variables))\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : Add Names to all zod schemas in src/zod_schemas.ts, eg: using Schema.describe('IInvokeSchema')\n\nCurrent files:\n[\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\n/** Schema for listing files in a directory */\\nexport const FileListingOptionsSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n}).describe('IFileListingOptions');\\n\\n/** Schema for file removal operations */\\nexport const FileRemovalOptionsSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n}).describe('IFileRemovalOptions');\\n\\n/** Schema for git commit operations */\\nexport const GitCommitSchema = z.object({\\n files: z.array(z.string()).describe('Files to commit'),\\n message: z.string().describe('Commit message')\\n}).describe('IGitCommitOptions');\\n\\n/** Schema for git revert operations */\\nexport const GitRevertSchema = z.object({\\n files: z.array(z.string()).describe('Files to revert')\\n}).describe('IGitRevertOptions');\\n\\n/** Schema for git version switch operations */\\nexport const GitSwitchVersionSchema = z.object({\\n branch: z.string().describe('Branch name to switch to'),\\n remote: z.string().default('origin').describe('Remote name')\\n}).describe('IGitSwitchVersionOptions');\\n\\n/** Schema for git raw file retrieval */\\nexport const GitRawFileSchema = z.object({\\n url: z.string().optional().describe('Full GitHub raw URL'),\\n repo: z.string().optional().describe('Repository in format owner/repo'),\\n path: z.string().optional().describe('File path within repository')\\n}).refine(\\n data => (data.url) || (data.repo && data.path),\\n 'Either url or both repo and path must be provided'\\n).describe('IGitRawFileOptions');\\n\\n/** Schema for npm run command */\\nexport const NpmRunSchema = z.object({\\n command: z.string().describe('Command to run (e.g. install, test, etc)'),\\n args: z.array(z.string()).optional().describe('Additional arguments for the command')\\n}).describe('INpmRunOptions');\\n\\n/** Schema for terminal command execution */\\nexport const TerminalCommandSchema = z.object({\\n command: z.string().describe('Command to execute'),\\n args: z.array(z.string()).optional().describe('Command arguments'),\\n cwd: z.string().optional().describe('Working directory for command execution'),\\n background: z.boolean().optional().describe('Run command in background (non-blocking)'),\\n window: z.boolean().optional().describe('Open command in new terminal window'),\\n detached: z.boolean().optional().describe('Run process detached from parent')\\n}).describe('ITerminalCommandOptions');\\n\\n/** Schema for tool invocation parameters */\\nexport const InvokeToolSchema = z.object({\\n tools: z.string().describe('Tool category to use (fs, npm, git, terminal)'),\\n function: z.string().describe('Function name to invoke'),\\n target: z.string().default(process.cwd()).describe('Target directory'),\\n params: z.string().optional().describe('JSON string of parameters'),\\n output: z.string().optional().describe('Path to write the output to'),\\n env_key: z.string().optional().describe('Environment configuration key')\\n}).describe('IInvokeToolOptions');\\n\\n/** Schema for list command options */\\nexport const ListCommandSchema = z.object({\\n output: z.string().default(\\\"./llm-tools.json\\\").describe('Output file path for tools list')\\n}).describe('IListCommandOptions');\\n\\n/** Schema for tool listing options */\\nexport const ToolListingOptionsSchema = z.object({\\n output: z.string().default('./llm-tools.json').describe('Path to write the output to')\\n}).describe('IToolListingOptions');\"\n },\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\",\\n \\\"list\\\": \\\"ts-node src/main.ts list\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"simple-git\\\": \\\"^3.22.0\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nCommand-line interface and library for LLM tools providing filesystem, npm, git, and terminal operations.\\n\\n## Setup\\n\\n1. Install dependencies:\\n```bash\\nnpm install\\n```\\n\\n2. Build the project:\\n```bash\\nnpm run build\\n```\\n\\n3. Configure environment:\\n```bash\\nexport OPENAI_API_KEY=your-key-here\\n# or use config file with --env_key parameter\\n```\\n\\n## Available Commands\\n\\n### Generate TypeScript Types\\n```bash\\nnpm run types\\n```\\n\\n### File Operations\\n```bash\\n# List files\\nnpm start files list --directory ./src --pattern \\\"**/*.ts\\\"\\n\\n# Remove files\\nnpm start files remove --path ./temp.txt\\n```\\n\\n### Git Operations\\n```bash\\n# Commit files\\nnpm start git commit --files file1.ts file2.ts --message \\\"commit message\\\"\\n\\n# Revert files\\nnpm start git revert --files file1.ts file2.ts\\n\\n# Switch branch\\nnpm start git switch --branch main --remote origin\\n\\n# Get raw file from GitHub\\nnpm start git raw --url \\\"https://raw...\\\" \\n# or\\nnpm start git raw --repo \\\"owner/repo\\\" --path \\\"path/to/file\\\"\\n```\\n\\n### NPM Commands\\n```bash\\nnpm start npm run --command install --args \\\"-D\\\" \\\"typescript\\\"\\n```\\n\\n### Terminal Commands\\n```bash\\nnpm start terminal exec --command \\\"echo\\\" --args \\\"hello\\\" --cwd \\\"./\\\"\\n```\\n\\n## Library Usage\\n\\n### Import Logger\\n```typescript\\nimport { Logger } from 'tslog'\\nimport { createLogger } from '@plastichub/osr-log'\\n\\nexport const logger: Logger = createLogger('package-name')\\n```\\n\\n### Access Configuration\\n```typescript\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\\n\\nconst config = CONFIG_DEFAULT('env_key')\\nif (!config) {\\n logger.warn('No config found!')\\n return\\n}\\nif (!config.openai?.key) {\\n logger.warn('No OpenAI key found in config!')\\n return\\n}\\nconst api_key = process.env.OPENAI_API_KEY || config.openai.key\\n```\\n\\n### File Operations\\n```typescript\\nimport { sync as rm } from '@plastichub/fs/remove'\\nimport { sync as dir } from '@plastichub/fs/dir'\\nimport { sync as write } from '@plastichub/fs/write'\\nimport { sync as read } from '@plastichub/fs/read'\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob'\\n\\n// Create/ensure directory\\ndir('path/to/dir')\\n\\n// Write file\\nwrite('file.txt', 'content')\\n\\n// Read file\\nconst content = read('file.txt')\\n\\n// Remove file\\nrm('file.txt')\\n\\n// Get files by glob pattern\\nconst files = glob('src', ['**/*.ts'])\\n```\\n\\n### Using Zod Schemas\\n```typescript\\nimport { toYargs } from '@plastichub/osr-commons'\\nimport { MySchema } from './zod_schemas'\\n\\n// Convert Zod schema to Yargs options\\nconst options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\\n```\\n\\n### Generate TypeScript Interfaces from Schemas\\n```typescript\\nimport { generate_interfaces } from '@plastichub/osr-commons'\\nimport { MySchema } from './zod_schemas'\\n\\nexport const types = () => generate_interfaces(\\n [MySchema()],\\n 'src/zod_types.ts'\\n)\\n```\\n\\n### Create LLM Tools\\n```typescript\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\\nimport { logger } from '../'\\n\\nexport const tools = (target: any, variables: Record = {}): Array => [\\n {\\n type: 'function',\\n function: {\\n name: \\\"tool_name\\\",\\n description: \\\"Tool description\\\",\\n parameters: {\\n type: \\\"object\\\",\\n properties: {\\n // tool parameters\\n },\\n required: [\\\"param1\\\"],\\n },\\n function: async (params) => {\\n try {\\n // tool implementation\\n } catch (error) {\\n logger.error(`Error in tool`, error)\\n } \\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction<{ id: string }>\\n]\\n```\\n\\n## Project Structure\\n```\\nsrc/\\n ├── commands/ # Command implementations\\n │ ├── index.ts # Command registry\\n │ └── types.ts # Types command\\n ├── lib/ # Core functionality\\n │ └── tools/ # Tool implementations\\n ├── constants.ts # Logger name constant\\n ├── index.ts # Logger setup\\n ├── main.ts # CLI entry point\\n └── zod_schemas.ts # Zod schemas\\n```\\n\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T13:43:27.528Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n### LLM Tools\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { resolve } from \"@plastichub/osr-commons\"\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any, variables:Record={}): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = path.resolve(resolve(join(target, file.path),false,variables))\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : Create a compelling readme.md\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\",\\n \\\"list\\\": \\\"ts-node src/main.ts list\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"simple-git\\\": \\\"^3.22.0\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nCommand-line interface and library for LLM tools providing filesystem, npm, git, and terminal operations.\\n\\n## Setup\\n\\n1. Install dependencies:\\n```bash\\nnpm install\\n```\\n\\n2. Build the project:\\n```bash\\nnpm run build\\n```\\n\\n3. Configure environment:\\nEither set environment variable:\\n```bash\\nexport OPENAI_API_KEY=your-key-here\\n```\\nOr create a configuration file (e.g. `.env.dev.json`):\\n```json\\n{\\n \\\"openai\\\": {\\n \\\"key\\\": \\\"your-key-here\\\"\\n }\\n}\\n```\\nThen use with --env_key parameter:\\n```bash\\nnpm start invoke --env_key dev\\n```\\n\\n## Available Commands\\n\\n### Generate TypeScript Types\\nGenerates TypeScript interfaces from Zod schemas:\\n```bash\\nnpm run types\\n```\\n\\n### File Operations\\n```bash\\n# List files in directory\\nnpm start fs list --directory ./src --pattern \\\"**/*.ts\\\"\\n\\n# Remove files\\nnpm start fs remove --path ./temp.txt\\n\\n# Read file content\\nnpm start fs read --path ./src/config.json\\n\\n# Write file\\nnpm start fs write --path ./output.txt --content \\\"Hello World\\\"\\n```\\n\\n### Git Operations\\n```bash\\n# Commit files\\nnpm start git commit --files src/index.ts src/main.ts --message \\\"Updated core files\\\"\\n\\n# Revert files\\nnpm start git revert --files src/config.ts\\n\\n# Switch branch\\nnpm start git switch --branch main --remote origin\\n\\n# Get raw file from GitHub\\nnpm start git raw --url \\\"https://raw.githubusercontent.com/user/repo/main/file.txt\\\"\\n# or\\nnpm start git raw --repo \\\"user/repo\\\" --path \\\"path/to/file.txt\\\"\\n```\\n\\n### NPM Commands\\n```bash\\n# Install dependencies\\nnpm start npm run --command install --args \\\"-D\\\" \\\"typescript\\\"\\n\\n# Run scripts\\nnpm start npm run --command test\\n```\\n\\n### Terminal Commands\\n```bash\\n# Basic command\\nnpm start terminal exec --command \\\"echo\\\" --args \\\"hello\\\"\\n\\n# With working directory\\nnpm start terminal exec --command \\\"ls\\\" --cwd \\\"./src\\\"\\n\\n# Background process\\nnpm start terminal exec --command \\\"serve\\\" --background true\\n\\n# New window\\nnpm start terminal exec --command \\\"vim\\\" --window true\\n```\\n\\n## Library Usage\\n\\n### Core Imports\\nAlways use ES imports:\\n```typescript\\nimport * as path from 'path'\\nimport * as fs from 'fs'\\n```\\n\\n### Logger Setup\\n```typescript\\nimport { Logger } from 'tslog'\\nimport { createLogger } from '@plastichub/osr-log'\\n\\nexport const logger: Logger = createLogger('package-name')\\n```\\n\\n### Configuration Access\\n```typescript\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\\n\\nconst config = CONFIG_DEFAULT('env_key')\\nif (!config) {\\n logger.warn('No config found!')\\n return\\n}\\nif (!config.openai?.key) {\\n logger.warn('No OpenAI key found in config!')\\n return\\n}\\nconst api_key = process.env.OPENAI_API_KEY || config.openai.key\\n```\\n\\n### File Operations\\n```typescript\\nimport { sync as rm } from '@plastichub/fs/remove'\\nimport { sync as dir } from '@plastichub/fs/dir'\\nimport { sync as write } from '@plastichub/fs/write'\\nimport { sync as read } from '@plastichub/fs/read'\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob'\\n\\n// Create/ensure directory\\nawait dir('path/to/dir')\\n\\n// Write file\\nawait write('file.txt', 'content')\\n\\n// Read file\\nconst content = await read('file.txt')\\n\\n// Remove file\\nawait rm('file.txt')\\n\\n// Get files by glob pattern\\nconst files = await glob('src', ['**/*.ts'])\\n```\\n\\n### Using Zod Schemas\\n```typescript\\nimport { toYargs } from '@plastichub/osr-commons'\\nimport { FileListingOptionsSchema } from './zod_schemas'\\n\\n// Convert Zod schema to Yargs options\\nconst options = (yargs: CLI.Argv) => toYargs(yargs, FileListingOptionsSchema)\\n```\\n\\n### Generate TypeScript Interfaces\\n```typescript\\nimport { generate_interfaces } from '@plastichub/osr-commons'\\nimport { FileListingOptionsSchema } from './zod_schemas'\\n\\nexport const types = () => generate_interfaces(\\n [FileListingOptionsSchema],\\n 'src/zod_types.ts'\\n)\\n```\\n\\n### Create LLM Tools\\n```typescript\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\\nimport { logger } from '../'\\n\\nexport const tools = (target: any, variables: Record = {}): Array => [\\n {\\n type: 'function',\\n function: {\\n name: \\\"read_file\\\",\\n description: \\\"Read file content\\\",\\n parameters: {\\n type: \\\"object\\\",\\n properties: {\\n path: { type: \\\"string\\\" }\\n },\\n required: [\\\"path\\\"],\\n },\\n function: async ({ path }) => {\\n try {\\n const content = await read(path)\\n return content\\n } catch (error) {\\n logger.error(`Error reading file`, error)\\n throw error\\n } \\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction<{ id: string }>\\n]\\n```\\n\\n## Project Structure\\n```\\nsrc/\\n ├── commands/ # Command implementations\\n │ ├── index.ts # Command registry\\n │ └── types.ts # Types command\\n ├── lib/ # Core functionality\\n │ └── tools/ # Tool implementations\\n ├── constants.ts # Logger name constant\\n ├── index.ts # Logger setup\\n ├── main.ts # CLI entry point\\n ├── zod_schemas.ts # Zod schemas\\n └── zod_types.ts # Generated TypeScript interfaces\\n```\\n\\n## Notes\\n\\n- All commands are asynchronous when using yargs\\n- Use tslog for consistent logging across the application\\n- Always use Zod schemas for command parameters\\n- Use axios for HTTP requests\\n- Configuration can be provided via environment variables or config files\\n- TypeScript interfaces can be generated from Zod schemas using the `types` command\\n\"\n },\n {\n \"path\": \"src\\\\zod_types.ts\",\n \"content\": \"export interface IFileListingOptions {\\n /** Directory path to list files from */\\n directory: string;\\n /** Glob pattern for filtering files */\\n pattern?: string | undefined;\\n}\\nexport interface IFileRemovalOptions {\\n /** Path of the file to remove */\\n path: string;\\n}\\nexport interface IGitCommitOptions {\\n /** Files to commit */\\n files: string[];\\n /** Commit message */\\n message: string;\\n}\\nexport interface IGitRevertOptions {\\n /** Files to revert */\\n files: string[];\\n}\\nexport interface IGitSwitchVersionOptions {\\n /** Branch name to switch to */\\n branch: string;\\n /** Remote name */\\n remote?: string;\\n}\\nexport interface IInvokeToolOptions {\\n /** Tool category to use (fs, npm, git, terminal) */\\n tools: string;\\n /** Function name to invoke */\\n function: string;\\n /** Target directory */\\n target?: string;\\n /** JSON string of parameters */\\n params?: string | undefined;\\n /** Path to write the output to */\\n output?: string | undefined;\\n /** Environment configuration key */\\n env_key?: string | undefined;\\n}\\nexport interface IToolListingOptions {\\n /** Path to write the output to */\\n output?: string;\\n}\\nexport interface ITerminalCommandOptions {\\n /** Command to execute */\\n command: string;\\n /** Command arguments */\\n args?: string[] | undefined;\\n /** Working directory for command execution */\\n cwd?: string | undefined;\\n /** Run command in background (non-blocking) */\\n background?: boolean | undefined;\\n /** Open command in new terminal window */\\n window?: boolean | undefined;\\n /** Run process detached from parent */\\n detached?: boolean | undefined;\\n}\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\n/** Schema for listing files in a directory */\\nexport const FileListingOptionsSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n}).describe('IFileListingOptions')\\n\\n/** Schema for file removal operations */\\nexport const FileRemovalOptionsSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n}).describe('IFileRemovalOptions');\\n\\n/** Schema for git commit operations */\\nexport const GitCommitSchema = z.object({\\n files: z.array(z.string()).describe('Files to commit'),\\n message: z.string().describe('Commit message')\\n}).describe('IGitCommitOptions');\\n\\n/** Schema for git revert operations */\\nexport const GitRevertSchema = z.object({\\n files: z.array(z.string()).describe('Files to revert')\\n}).describe('IGitRevertOptions');\\n\\n/** Schema for git version switch operations */\\nexport const GitSwitchVersionSchema = z.object({\\n branch: z.string().describe('Branch name to switch to'),\\n remote: z.string().default('origin').describe('Remote name')\\n}).describe('IGitSwitchVersionOptions');\\n\\n/** Schema for git raw file retrieval */\\nexport const GitRawFileSchema = z.object({\\n url: z.string().optional().describe('Full GitHub raw URL'),\\n repo: z.string().optional().describe('Repository in format owner/repo'),\\n path: z.string().optional().describe('File path within repository')\\n}).refine(\\n data => (data.url) || (data.repo && data.path),\\n 'Either url or both repo and path must be provided'\\n).describe('IGitRawFileOptions');\\n\\n/** Schema for npm run command */\\nexport const NpmRunSchema = z.object({\\n command: z.string().describe('Command to run (e.g. install, test, etc)'),\\n args: z.array(z.string()).optional().describe('Additional arguments for the command')\\n}).describe('INpmRunOptions');\\n\\n/** Schema for terminal command execution */\\nexport const TerminalCommandSchema = z.object({\\n command: z.string().describe('Command to execute'),\\n args: z.array(z.string()).optional().describe('Command arguments'),\\n cwd: z.string().optional().describe('Working directory for command execution'),\\n background: z.boolean().optional().describe('Run command in background (non-blocking)'),\\n window: z.boolean().optional().describe('Open command in new terminal window'),\\n detached: z.boolean().optional().describe('Run process detached from parent')\\n}).describe('ITerminalCommandOptions');\\n\\n/** Schema for tool invocation parameters */\\nexport const InvokeToolSchema = z.object({\\n tools: z.string().describe('Tool category to use (fs, npm, git, terminal)'),\\n function: z.string().describe('Function name to invoke'),\\n target: z.string().default(process.cwd()).describe('Target directory'),\\n params: z.string().optional().describe('JSON string of parameters'),\\n output: z.string().optional().describe('Path to write the output to'),\\n env_key: z.string().optional().describe('Environment configuration key')\\n}).describe('IInvokeToolOptions');\\n\\n/** Schema for list command options */\\nexport const ListCommandSchema = z.object({\\n output: z.string().default(\\\"./llm-tools.json\\\").describe('Output file path for tools list')\\n}).describe('IListCommandOptions');\\n\\n/** Schema for tool listing options */\\nexport const ToolListingOptionsSchema = z.object({\\n output: z.string().default('./llm-tools.json').describe('Path to write the output to')\\n}).describe('IToolListingOptions');\"\n },\n {\n \"path\": \"src\\\\tools.ts\",\n \"content\": \"import { tools as fsTools } from './lib/tools/fs';\\nimport { tools as npmTools } from './lib/tools/npm';\\nimport { tools as gitTools } from './lib/tools/git';\\nimport { tools as terminalTools } from './lib/tools/terminal';\\n\\nexport const tools = {\\n fs: fsTools,\\n npm: npmTools,\\n git: gitTools,\\n terminal: terminalTools\\n};\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport yargs from 'yargs';\\nimport { commands } from './commands';\\nimport { logger } from './';\\n\\nasync function main() {\\n try {\\n const argv = await commands(yargs).argv;\\n } catch (error) {\\n logger.error('Error executing command:', error);\\n process.exit(1);\\n }\\n}\\n\\nmain();\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\terminal.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec, spawn } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'execute_command',\\n description: 'Execute a terminal command and capture output',\\n parameters: {\\n type: 'object',\\n properties: {\\n command: { \\n type: 'string',\\n description: 'Command to execute'\\n },\\n args: {\\n type: 'array',\\n items: { type: 'string' },\\n description: 'Command arguments',\\n optional: true\\n },\\n cwd: {\\n type: 'string',\\n description: 'Working directory for command execution',\\n optional: true\\n },\\n background: {\\n type: 'boolean',\\n description: 'Run command in background (non-blocking)',\\n optional: true\\n },\\n window: {\\n type: 'boolean',\\n description: 'Open command in new terminal window',\\n optional: true\\n },\\n detached: {\\n type: 'boolean',\\n description: 'Run process detached from parent',\\n optional: true\\n }\\n },\\n required: ['command']\\n },\\n function: async (params: any) => {\\n try {\\n const workingDir = params.cwd ? path.join(target, params.cwd) : target;\\n const args = params.args || [];\\n \\n // Handle window mode (platform specific)\\n if (params.window) {\\n const isWindows = process.platform === 'win32';\\n if (isWindows) {\\n spawn('cmd', ['/c', 'start', 'cmd', '/k', params.command, ...args], {\\n cwd: workingDir,\\n detached: true,\\n stdio: 'ignore'\\n });\\n } else {\\n // For macOS/Linux\\n spawn('x-terminal-emulator', ['-e', `${params.command} ${args.join(' ')}`], {\\n cwd: workingDir,\\n detached: true,\\n stdio: 'ignore'\\n });\\n }\\n return {\\n success: true,\\n output: 'Command launched in new window',\\n error: null\\n };\\n }\\n\\n // Handle background/detached mode\\n if (params.background || params.detached) {\\n const child = spawn(params.command, args, {\\n cwd: workingDir,\\n detached: params.detached === true,\\n stdio: 'ignore'\\n });\\n\\n if (params.detached) {\\n child.unref();\\n }\\n\\n return {\\n success: true,\\n output: `Process started with PID: ${child.pid}`,\\n error: null\\n };\\n }\\n\\n // Regular synchronous execution\\n const fullCommand = `${params.command} ${args.join(' ')}`.trim();\\n logger.debug(`Tool::ExecuteCommand Running '${fullCommand}' in ${workingDir}`);\\n const { stdout, stderr } = await execAsync(fullCommand, {\\n cwd: workingDir\\n });\\n\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error: any) {\\n logger.error('Error executing command', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\npm.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'build_project',\\n description: 'Build project using pnpm build command',\\n parameters: {\\n type: 'object',\\n properties: {},\\n required: []\\n },\\n function: async () => {\\n try {\\n logger.debug(`Tool::BuildProject Building project at ${target}`);\\n const { stdout, stderr } = await execAsync('pnpm build', {\\n cwd: target\\n });\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error : any) {\\n logger.error('Error building project', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'run_npm',\\n description: 'Run an npm/pnpm command',\\n parameters: {\\n type: 'object',\\n properties: {\\n command: { type: 'string', description: 'Command to run (e.g. install, test, etc)' },\\n args: { \\n type: 'array',\\n items: { type: 'string' },\\n description: 'Additional arguments for the command',\\n optional: true\\n }\\n },\\n required: ['command']\\n },\\n function: async (params: any) => {\\n try {\\n const args = params.args ? params.args.join(' ') : '';\\n const fullCommand = `pnpm ${params.command} ${args}`.trim();\\n logger.debug(`Tool::RunNpm Running command: ${fullCommand}`);\\n const { stdout, stderr } = await execAsync(fullCommand, {\\n cwd: target\\n });\\n\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error: any) {\\n logger.error('Error running npm command', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\git.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport simpleGit, { SimpleGit } from 'simple-git';\\nimport axios from 'axios';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n const git: SimpleGit = simpleGit(target);\\n\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'commit_files',\\n description: 'Commit files to git repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n files: {\\n type: 'array',\\n items: { type: 'string' }\\n },\\n message: { type: 'string' }\\n },\\n required: ['files', 'message']\\n },\\n function: async (params: any) => {\\n try {\\n logger.debug(`Tool::Git Committing files with message: ${params.message}`);\\n await git.add(params.files);\\n const result = await git.commit(params.message);\\n return {\\n success: true,\\n output: result,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error committing files', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'revert_files',\\n description: 'Revert specified files in git repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n files: {\\n type: 'array',\\n items: { type: 'string' }\\n }\\n },\\n required: ['files']\\n },\\n function: async (params: any) => {\\n try {\\n logger.debug(`Tool::Git Reverting files: ${params.files.join(', ')}`);\\n await git.checkout(['--', ...params.files]);\\n return {\\n success: true,\\n output: 'Files reverted successfully',\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error reverting files', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'switch_version',\\n description: 'Switch to previous version from remote',\\n parameters: {\\n type: 'object',\\n properties: {\\n branch: { type: 'string' },\\n remote: { \\n type: 'string',\\n default: 'origin'\\n }\\n },\\n required: ['branch']\\n },\\n function: async (params: any) => {\\n try {\\n const remote = params.remote || 'origin';\\n logger.debug(`Tool::Git Switching to branch ${params.branch} from ${remote}`);\\n const result = await git.checkout(`${remote}/${params.branch}`);\\n return {\\n success: true,\\n output: result,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error switching version', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'get_raw_file',\\n description: 'Retrieve raw content of a file from GitHub repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n url: { \\n type: 'string',\\n description: 'Full GitHub raw URL or repository path'\\n },\\n repo: {\\n type: 'string',\\n description: 'Repository in format owner/repo'\\n },\\n path: {\\n type: 'string',\\n description: 'File path within repository'\\n }\\n },\\n oneOf: [\\n { required: ['url'] },\\n { required: ['repo', 'path'] }\\n ]\\n },\\n function: async (params: any) => {\\n try {\\n let fileUrl = params.url;\\n if (!fileUrl && params.repo && params.path) {\\n fileUrl = `https://raw.githubusercontent.com/${params.repo}/main/${params.path}`;\\n }\\n \\n logger.debug(`Tool::Git Fetching raw file from ${fileUrl}`);\\n const response = await axios.get(fileUrl);\\n return {\\n success: true,\\n content: response.data,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error fetching raw file', error);\\n return {\\n success: false,\\n content: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { \\n FileListingOptionsSchema, \\n FileRemovalOptionsSchema,\\n GitCommitSchema,\\n GitRevertSchema,\\n GitSwitchVersionSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema,\\n TerminalCommandSchema \\n} from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n FileListingOptionsSchema,\\n FileRemovalOptionsSchema,\\n GitCommitSchema,\\n GitRevertSchema,\\n GitSwitchVersionSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema,\\n TerminalCommandSchema\\n ], 'src/zod_types.ts');\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\list.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { ListCommandSchema } from '../zod_schemas';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport type { Argv } from 'yargs';\\n\\nexport const options = (yargs: Argv) => toYargs(yargs, ListCommandSchema);\\n\\nexport const list = async (argv: any) => {\\n // Initialize tools with current directory\\n const fsTools = tools.fs(process.cwd());\\n const npmTools = tools.npm(process.cwd());\\n const gitTools = tools.git(process.cwd());\\n const terminalTools = tools.terminal(process.cwd());\\n\\n const toolsList = {\\n fs: fsTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'fs'\\n })),\\n npm: npmTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'npm'\\n })),\\n git: gitTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'git'\\n })),\\n terminal: terminalTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'terminal'\\n }))\\n };\\n\\n logger.info('Available Tools:\\\\n');\\n \\n logger.info('Filesystem Tools:');\\n fsTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nNPM Tools:');\\n npmTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nGit Tools:');\\n gitTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nTerminal Tools:');\\n terminalTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n if (argv.output) {\\n logger.info(`\\\\nWriting tools list to ${argv.output}`);\\n write(argv.output, JSON.stringify(toolsList, null, 2));\\n }\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\invoke.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { InvokeToolSchema } from '../zod_schemas';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport type { Argv } from 'yargs';\\nimport * as path from 'path';\\n\\nconst options = (yargs: Argv) => toYargs(yargs, InvokeToolSchema);\\n\\nexport const invoke = async (argv: any) => {\\n try {\\n const { tools: toolCategory, function: funcName, target, params, output } = argv;\\n \\n // Get tool category\\n const toolSet = tools[toolCategory];\\n if (!toolSet) {\\n logger.error(`Tool category '${toolCategory}' not found`);\\n return;\\n }\\n\\n // Initialize tools with target directory\\n const toolList = toolSet(target);\\n \\n // Find specific function\\n const tool = toolList.find(t => t.function.name === funcName);\\n if (!tool) {\\n logger.error(`Function '${funcName}' not found in ${toolCategory} tools`);\\n return;\\n }\\n\\n // Parse parameters if provided\\n const parameters = params ? JSON.parse(params) : {};\\n \\n // Execute tool function\\n logger.info(`Invoking ${toolCategory}::${funcName}`);\\n const result = await tool.function.function(parameters);\\n \\n // Handle output\\n if (output) {\\n const outputPath = path.isAbsolute(output) ? output : path.join(process.cwd(), output);\\n logger.info(`Writing output to ${outputPath}`);\\n write(outputPath, JSON.stringify(result, null, 2));\\n } else {\\n logger.info('Result:', result);\\n }\\n \\n return result;\\n } catch (error) {\\n logger.error('Error invoking tool:', error);\\n throw error;\\n }\\n};\\n\\nexport { options as invokeOptions };\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\nimport { list, options as listOptions } from './list';\\nimport { invoke, invokeOptions } from './invoke';\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons';\\nimport { logger } from '../';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .command('list', 'List all available tools and their descriptions', listOptions, list)\\n .command('invoke', 'Invoke a specific tool function', invokeOptions, invoke)\\n .option('env_key', {\\n type: 'string',\\n description: 'Environment configuration key'\\n })\\n .middleware([(argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any;\\n if (!config) {\\n logger.warn('No config found!');\\n return;\\n }\\n return config;\\n }])\\n .strict()\\n .help();\\n};\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T13:49:25.493Z" - }, - { - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n### LLM Tools\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { resolve } from \"@plastichub/osr-commons\"\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any, variables:Record={}): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = path.resolve(resolve(join(target, file.path),false,variables))\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : Update package.json for tools (scripts)\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\",\\n \\\"list\\\": \\\"ts-node src/main.ts list\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"simple-git\\\": \\\"^3.22.0\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nCommand-line interface and library for LLM tools providing filesystem, npm, git, and terminal operations.\\n\\n## Setup\\n\\n1. Install dependencies:\\n```bash\\nnpm install\\n```\\n\\n2. Build the project:\\n```bash\\nnpm run build\\n```\\n\\n3. Configure environment:\\nEither set environment variable:\\n```bash\\nexport OPENAI_API_KEY=your-key-here\\n```\\nOr create a configuration file (e.g. `.env.dev.json`):\\n```json\\n{\\n \\\"openai\\\": {\\n \\\"key\\\": \\\"your-key-here\\\"\\n }\\n}\\n```\\nThen use with --env_key parameter:\\n```bash\\nnpm start invoke --env_key dev\\n```\\n\\n## Available Commands\\n\\n### Generate TypeScript Types\\nGenerates TypeScript interfaces from Zod schemas:\\n```bash\\nnpm run types\\n```\\n\\n### File Operations\\n```bash\\n# List files in directory\\nnpm start fs list --directory ./src --pattern \\\"**/*.ts\\\"\\n\\n# Remove files\\nnpm start fs remove --path ./temp.txt\\n\\n# Read file content\\nnpm start fs read --path ./src/config.json\\n\\n# Write file\\nnpm start fs write --path ./output.txt --content \\\"Hello World\\\"\\n```\\n\\n### Git Operations\\n```bash\\n# Commit files\\nnpm start git commit --files src/index.ts src/main.ts --message \\\"Updated core files\\\"\\n\\n# Revert files\\nnpm start git revert --files src/config.ts\\n\\n# Switch branch\\nnpm start git switch --branch main --remote origin\\n\\n# Get raw file from GitHub\\nnpm start git raw --url \\\"https://raw.githubusercontent.com/user/repo/main/file.txt\\\"\\n# or\\nnpm start git raw --repo \\\"user/repo\\\" --path \\\"path/to/file.txt\\\"\\n```\\n\\n### NPM Commands\\n```bash\\n# Install dependencies\\nnpm start npm run --command install --args \\\"-D\\\" \\\"typescript\\\"\\n\\n# Run scripts\\nnpm start npm run --command test\\n```\\n\\n### Terminal Commands\\n```bash\\n# Basic command\\nnpm start terminal exec --command \\\"echo\\\" --args \\\"hello\\\"\\n\\n# With working directory\\nnpm start terminal exec --command \\\"ls\\\" --cwd \\\"./src\\\"\\n\\n# Background process\\nnpm start terminal exec --command \\\"serve\\\" --background true\\n\\n# New window\\nnpm start terminal exec --command \\\"vim\\\" --window true\\n```\\n\\n## Library Usage\\n\\n### Core Imports\\nAlways use ES imports:\\n```typescript\\nimport * as path from 'path'\\nimport * as fs from 'fs'\\n```\\n\\n### Logger Setup\\n```typescript\\nimport { Logger } from 'tslog'\\nimport { createLogger } from '@plastichub/osr-log'\\n\\nexport const logger: Logger = createLogger('package-name')\\n```\\n\\n### Configuration Access\\n```typescript\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\\n\\nconst config = CONFIG_DEFAULT('env_key')\\nif (!config) {\\n logger.warn('No config found!')\\n return\\n}\\nif (!config.openai?.key) {\\n logger.warn('No OpenAI key found in config!')\\n return\\n}\\nconst api_key = process.env.OPENAI_API_KEY || config.openai.key\\n```\\n\\n### File Operations\\n```typescript\\nimport { sync as rm } from '@plastichub/fs/remove'\\nimport { sync as dir } from '@plastichub/fs/dir'\\nimport { sync as write } from '@plastichub/fs/write'\\nimport { sync as read } from '@plastichub/fs/read'\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob'\\n\\n// Create/ensure directory\\nawait dir('path/to/dir')\\n\\n// Write file\\nawait write('file.txt', 'content')\\n\\n// Read file\\nconst content = await read('file.txt')\\n\\n// Remove file\\nawait rm('file.txt')\\n\\n// Get files by glob pattern\\nconst files = await glob('src', ['**/*.ts'])\\n```\\n\\n### Using Zod Schemas\\n```typescript\\nimport { toYargs } from '@plastichub/osr-commons'\\nimport { FileListingOptionsSchema } from './zod_schemas'\\n\\n// Convert Zod schema to Yargs options\\nconst options = (yargs: CLI.Argv) => toYargs(yargs, FileListingOptionsSchema)\\n```\\n\\n### Generate TypeScript Interfaces\\n```typescript\\nimport { generate_interfaces } from '@plastichub/osr-commons'\\nimport { FileListingOptionsSchema } from './zod_schemas'\\n\\nexport const types = () => generate_interfaces(\\n [FileListingOptionsSchema],\\n 'src/zod_types.ts'\\n)\\n```\\n\\n### Create LLM Tools\\n```typescript\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\\nimport { logger } from '../'\\n\\nexport const tools = (target: any, variables: Record = {}): Array => [\\n {\\n type: 'function',\\n function: {\\n name: \\\"read_file\\\",\\n description: \\\"Read file content\\\",\\n parameters: {\\n type: \\\"object\\\",\\n properties: {\\n path: { type: \\\"string\\\" }\\n },\\n required: [\\\"path\\\"],\\n },\\n function: async ({ path }) => {\\n try {\\n const content = await read(path)\\n return content\\n } catch (error) {\\n logger.error(`Error reading file`, error)\\n throw error\\n } \\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction<{ id: string }>\\n]\\n```\\n\\n## Project Structure\\n```\\nsrc/\\n ├── commands/ # Command implementations\\n │ ├── index.ts # Command registry\\n │ └── types.ts # Types command\\n ├── lib/ # Core functionality\\n │ └── tools/ # Tool implementations\\n ├── constants.ts # Logger name constant\\n ├── index.ts # Logger setup\\n ├── main.ts # CLI entry point\\n ├── zod_schemas.ts # Zod schemas\\n └── zod_types.ts # Generated TypeScript interfaces\\n```\\n\\n## Notes\\n\\n- All commands are asynchronous when using yargs\\n- Use tslog for consistent logging across the application\\n- Always use Zod schemas for command parameters\\n- Use axios for HTTP requests\\n- Configuration can be provided via environment variables or config files\\n- TypeScript interfaces can be generated from Zod schemas using the `types` command\\n\"\n },\n {\n \"path\": \"src\\\\zod_types.ts\",\n \"content\": \"export interface IFileListingOptions {\\n /** Directory path to list files from */\\n directory: string;\\n /** Glob pattern for filtering files */\\n pattern?: string | undefined;\\n}\\nexport interface IFileRemovalOptions {\\n /** Path of the file to remove */\\n path: string;\\n}\\nexport interface IGitCommitOptions {\\n /** Files to commit */\\n files: string[];\\n /** Commit message */\\n message: string;\\n}\\nexport interface IGitRevertOptions {\\n /** Files to revert */\\n files: string[];\\n}\\nexport interface IGitSwitchVersionOptions {\\n /** Branch name to switch to */\\n branch: string;\\n /** Remote name */\\n remote?: string;\\n}\\nexport interface IInvokeToolOptions {\\n /** Tool category to use (fs, npm, git, terminal) */\\n tools: string;\\n /** Function name to invoke */\\n function: string;\\n /** Target directory */\\n target?: string;\\n /** JSON string of parameters */\\n params?: string | undefined;\\n /** Path to write the output to */\\n output?: string | undefined;\\n /** Environment configuration key */\\n env_key?: string | undefined;\\n}\\nexport interface IToolListingOptions {\\n /** Path to write the output to */\\n output?: string;\\n}\\nexport interface ITerminalCommandOptions {\\n /** Command to execute */\\n command: string;\\n /** Command arguments */\\n args?: string[] | undefined;\\n /** Working directory for command execution */\\n cwd?: string | undefined;\\n /** Run command in background (non-blocking) */\\n background?: boolean | undefined;\\n /** Open command in new terminal window */\\n window?: boolean | undefined;\\n /** Run process detached from parent */\\n detached?: boolean | undefined;\\n}\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\n/** Schema for listing files in a directory */\\nexport const FileListingOptionsSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n}).describe('IFileListingOptions')\\n\\n/** Schema for file removal operations */\\nexport const FileRemovalOptionsSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n}).describe('IFileRemovalOptions');\\n\\n/** Schema for git commit operations */\\nexport const GitCommitSchema = z.object({\\n files: z.array(z.string()).describe('Files to commit'),\\n message: z.string().describe('Commit message')\\n}).describe('IGitCommitOptions');\\n\\n/** Schema for git revert operations */\\nexport const GitRevertSchema = z.object({\\n files: z.array(z.string()).describe('Files to revert')\\n}).describe('IGitRevertOptions');\\n\\n/** Schema for git version switch operations */\\nexport const GitSwitchVersionSchema = z.object({\\n branch: z.string().describe('Branch name to switch to'),\\n remote: z.string().default('origin').describe('Remote name')\\n}).describe('IGitSwitchVersionOptions');\\n\\n/** Schema for git raw file retrieval */\\nexport const GitRawFileSchema = z.object({\\n url: z.string().optional().describe('Full GitHub raw URL'),\\n repo: z.string().optional().describe('Repository in format owner/repo'),\\n path: z.string().optional().describe('File path within repository')\\n}).refine(\\n data => (data.url) || (data.repo && data.path),\\n 'Either url or both repo and path must be provided'\\n).describe('IGitRawFileOptions');\\n\\n/** Schema for npm run command */\\nexport const NpmRunSchema = z.object({\\n command: z.string().describe('Command to run (e.g. install, test, etc)'),\\n args: z.array(z.string()).optional().describe('Additional arguments for the command')\\n}).describe('INpmRunOptions');\\n\\n/** Schema for terminal command execution */\\nexport const TerminalCommandSchema = z.object({\\n command: z.string().describe('Command to execute'),\\n args: z.array(z.string()).optional().describe('Command arguments'),\\n cwd: z.string().optional().describe('Working directory for command execution'),\\n background: z.boolean().optional().describe('Run command in background (non-blocking)'),\\n window: z.boolean().optional().describe('Open command in new terminal window'),\\n detached: z.boolean().optional().describe('Run process detached from parent')\\n}).describe('ITerminalCommandOptions');\\n\\n/** Schema for tool invocation parameters */\\nexport const InvokeToolSchema = z.object({\\n tools: z.string().describe('Tool category to use (fs, npm, git, terminal)'),\\n function: z.string().describe('Function name to invoke'),\\n target: z.string().default(process.cwd()).describe('Target directory'),\\n params: z.string().optional().describe('JSON string of parameters'),\\n output: z.string().optional().describe('Path to write the output to'),\\n env_key: z.string().optional().describe('Environment configuration key')\\n}).describe('IInvokeToolOptions');\\n\\n/** Schema for list command options */\\nexport const ListCommandSchema = z.object({\\n output: z.string().default(\\\"./llm-tools.json\\\").describe('Output file path for tools list')\\n}).describe('IListCommandOptions');\\n\\n/** Schema for tool listing options */\\nexport const ToolListingOptionsSchema = z.object({\\n output: z.string().default('./llm-tools.json').describe('Path to write the output to')\\n}).describe('IToolListingOptions');\"\n },\n {\n \"path\": \"src\\\\tools.ts\",\n \"content\": \"import { tools as fsTools } from './lib/tools/fs';\\nimport { tools as npmTools } from './lib/tools/npm';\\nimport { tools as gitTools } from './lib/tools/git';\\nimport { tools as terminalTools } from './lib/tools/terminal';\\n\\nexport const tools = {\\n fs: fsTools,\\n npm: npmTools,\\n git: gitTools,\\n terminal: terminalTools\\n};\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport yargs from 'yargs';\\nimport { commands } from './commands';\\nimport { logger } from './';\\n\\nasync function main() {\\n try {\\n const argv = await commands(yargs).argv;\\n } catch (error) {\\n logger.error('Error executing command:', error);\\n process.exit(1);\\n }\\n}\\n\\nmain();\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\terminal.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec, spawn } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'execute_command',\\n description: 'Execute a terminal command and capture output',\\n parameters: {\\n type: 'object',\\n properties: {\\n command: { \\n type: 'string',\\n description: 'Command to execute'\\n },\\n args: {\\n type: 'array',\\n items: { type: 'string' },\\n description: 'Command arguments',\\n optional: true\\n },\\n cwd: {\\n type: 'string',\\n description: 'Working directory for command execution',\\n optional: true\\n },\\n background: {\\n type: 'boolean',\\n description: 'Run command in background (non-blocking)',\\n optional: true\\n },\\n window: {\\n type: 'boolean',\\n description: 'Open command in new terminal window',\\n optional: true\\n },\\n detached: {\\n type: 'boolean',\\n description: 'Run process detached from parent',\\n optional: true\\n }\\n },\\n required: ['command']\\n },\\n function: async (params: any) => {\\n try {\\n const workingDir = params.cwd ? path.join(target, params.cwd) : target;\\n const args = params.args || [];\\n \\n // Handle window mode (platform specific)\\n if (params.window) {\\n const isWindows = process.platform === 'win32';\\n if (isWindows) {\\n spawn('cmd', ['/c', 'start', 'cmd', '/k', params.command, ...args], {\\n cwd: workingDir,\\n detached: true,\\n stdio: 'ignore'\\n });\\n } else {\\n // For macOS/Linux\\n spawn('x-terminal-emulator', ['-e', `${params.command} ${args.join(' ')}`], {\\n cwd: workingDir,\\n detached: true,\\n stdio: 'ignore'\\n });\\n }\\n return {\\n success: true,\\n output: 'Command launched in new window',\\n error: null\\n };\\n }\\n\\n // Handle background/detached mode\\n if (params.background || params.detached) {\\n const child = spawn(params.command, args, {\\n cwd: workingDir,\\n detached: params.detached === true,\\n stdio: 'ignore'\\n });\\n\\n if (params.detached) {\\n child.unref();\\n }\\n\\n return {\\n success: true,\\n output: `Process started with PID: ${child.pid}`,\\n error: null\\n };\\n }\\n\\n // Regular synchronous execution\\n const fullCommand = `${params.command} ${args.join(' ')}`.trim();\\n logger.debug(`Tool::ExecuteCommand Running '${fullCommand}' in ${workingDir}`);\\n const { stdout, stderr } = await execAsync(fullCommand, {\\n cwd: workingDir\\n });\\n\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error: any) {\\n logger.error('Error executing command', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\npm.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'build_project',\\n description: 'Build project using pnpm build command',\\n parameters: {\\n type: 'object',\\n properties: {},\\n required: []\\n },\\n function: async () => {\\n try {\\n logger.debug(`Tool::BuildProject Building project at ${target}`);\\n const { stdout, stderr } = await execAsync('pnpm build', {\\n cwd: target\\n });\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error : any) {\\n logger.error('Error building project', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'run_npm',\\n description: 'Run an npm/pnpm command',\\n parameters: {\\n type: 'object',\\n properties: {\\n command: { type: 'string', description: 'Command to run (e.g. install, test, etc)' },\\n args: { \\n type: 'array',\\n items: { type: 'string' },\\n description: 'Additional arguments for the command',\\n optional: true\\n }\\n },\\n required: ['command']\\n },\\n function: async (params: any) => {\\n try {\\n const args = params.args ? params.args.join(' ') : '';\\n const fullCommand = `pnpm ${params.command} ${args}`.trim();\\n logger.debug(`Tool::RunNpm Running command: ${fullCommand}`);\\n const { stdout, stderr } = await execAsync(fullCommand, {\\n cwd: target\\n });\\n\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error: any) {\\n logger.error('Error running npm command', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\git.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport simpleGit, { SimpleGit } from 'simple-git';\\nimport axios from 'axios';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n const git: SimpleGit = simpleGit(target);\\n\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'commit_files',\\n description: 'Commit files to git repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n files: {\\n type: 'array',\\n items: { type: 'string' }\\n },\\n message: { type: 'string' }\\n },\\n required: ['files', 'message']\\n },\\n function: async (params: any) => {\\n try {\\n logger.debug(`Tool::Git Committing files with message: ${params.message}`);\\n await git.add(params.files);\\n const result = await git.commit(params.message);\\n return {\\n success: true,\\n output: result,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error committing files', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'revert_files',\\n description: 'Revert specified files in git repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n files: {\\n type: 'array',\\n items: { type: 'string' }\\n }\\n },\\n required: ['files']\\n },\\n function: async (params: any) => {\\n try {\\n logger.debug(`Tool::Git Reverting files: ${params.files.join(', ')}`);\\n await git.checkout(['--', ...params.files]);\\n return {\\n success: true,\\n output: 'Files reverted successfully',\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error reverting files', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'switch_version',\\n description: 'Switch to previous version from remote',\\n parameters: {\\n type: 'object',\\n properties: {\\n branch: { type: 'string' },\\n remote: { \\n type: 'string',\\n default: 'origin'\\n }\\n },\\n required: ['branch']\\n },\\n function: async (params: any) => {\\n try {\\n const remote = params.remote || 'origin';\\n logger.debug(`Tool::Git Switching to branch ${params.branch} from ${remote}`);\\n const result = await git.checkout(`${remote}/${params.branch}`);\\n return {\\n success: true,\\n output: result,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error switching version', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'get_raw_file',\\n description: 'Retrieve raw content of a file from GitHub repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n url: { \\n type: 'string',\\n description: 'Full GitHub raw URL or repository path'\\n },\\n repo: {\\n type: 'string',\\n description: 'Repository in format owner/repo'\\n },\\n path: {\\n type: 'string',\\n description: 'File path within repository'\\n }\\n },\\n oneOf: [\\n { required: ['url'] },\\n { required: ['repo', 'path'] }\\n ]\\n },\\n function: async (params: any) => {\\n try {\\n let fileUrl = params.url;\\n if (!fileUrl && params.repo && params.path) {\\n fileUrl = `https://raw.githubusercontent.com/${params.repo}/main/${params.path}`;\\n }\\n \\n logger.debug(`Tool::Git Fetching raw file from ${fileUrl}`);\\n const response = await axios.get(fileUrl);\\n return {\\n success: true,\\n content: response.data,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error fetching raw file', error);\\n return {\\n success: false,\\n content: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { \\n FileListingOptionsSchema, \\n FileRemovalOptionsSchema,\\n GitCommitSchema,\\n GitRevertSchema,\\n GitSwitchVersionSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema,\\n TerminalCommandSchema \\n} from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n FileListingOptionsSchema,\\n FileRemovalOptionsSchema,\\n GitCommitSchema,\\n GitRevertSchema,\\n GitSwitchVersionSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema,\\n TerminalCommandSchema\\n ], 'src/zod_types.ts');\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\list.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { ListCommandSchema } from '../zod_schemas';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport type { Argv } from 'yargs';\\n\\nexport const options = (yargs: Argv) => toYargs(yargs, ListCommandSchema);\\n\\nexport const list = async (argv: any) => {\\n // Initialize tools with current directory\\n const fsTools = tools.fs(process.cwd());\\n const npmTools = tools.npm(process.cwd());\\n const gitTools = tools.git(process.cwd());\\n const terminalTools = tools.terminal(process.cwd());\\n\\n const toolsList = {\\n fs: fsTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'fs'\\n })),\\n npm: npmTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'npm'\\n })),\\n git: gitTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'git'\\n })),\\n terminal: terminalTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'terminal'\\n }))\\n };\\n\\n logger.info('Available Tools:\\\\n');\\n \\n logger.info('Filesystem Tools:');\\n fsTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nNPM Tools:');\\n npmTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nGit Tools:');\\n gitTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nTerminal Tools:');\\n terminalTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n if (argv.output) {\\n logger.info(`\\\\nWriting tools list to ${argv.output}`);\\n write(argv.output, JSON.stringify(toolsList, null, 2));\\n }\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\invoke.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { InvokeToolSchema } from '../zod_schemas';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport type { Argv } from 'yargs';\\nimport * as path from 'path';\\n\\nconst options = (yargs: Argv) => toYargs(yargs, InvokeToolSchema);\\n\\nexport const invoke = async (argv: any) => {\\n try {\\n const { tools: toolCategory, function: funcName, target, params, output } = argv;\\n \\n // Get tool category\\n const toolSet = tools[toolCategory];\\n if (!toolSet) {\\n logger.error(`Tool category '${toolCategory}' not found`);\\n return;\\n }\\n\\n // Initialize tools with target directory\\n const toolList = toolSet(target);\\n \\n // Find specific function\\n const tool = toolList.find(t => t.function.name === funcName);\\n if (!tool) {\\n logger.error(`Function '${funcName}' not found in ${toolCategory} tools`);\\n return;\\n }\\n\\n // Parse parameters if provided\\n const parameters = params ? JSON.parse(params) : {};\\n \\n // Execute tool function\\n logger.info(`Invoking ${toolCategory}::${funcName}`);\\n const result = await tool.function.function(parameters);\\n \\n // Handle output\\n if (output) {\\n const outputPath = path.isAbsolute(output) ? output : path.join(process.cwd(), output);\\n logger.info(`Writing output to ${outputPath}`);\\n write(outputPath, JSON.stringify(result, null, 2));\\n } else {\\n logger.info('Result:', result);\\n }\\n \\n return result;\\n } catch (error) {\\n logger.error('Error invoking tool:', error);\\n throw error;\\n }\\n};\\n\\nexport { options as invokeOptions };\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\nimport { list, options as listOptions } from './list';\\nimport { invoke, invokeOptions } from './invoke';\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons';\\nimport { logger } from '../';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .command('list', 'List all available tools and their descriptions', listOptions, list)\\n .command('invoke', 'Invoke a specific tool function', invokeOptions, invoke)\\n .option('env_key', {\\n type: 'string',\\n description: 'Environment configuration key'\\n })\\n .middleware([(argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any;\\n if (!config) {\\n logger.warn('No config found!');\\n return;\\n }\\n return config;\\n }])\\n .strict()\\n .help();\\n};\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto", - "ts": "2024-12-15T13:50:56.412Z" - } -] \ No newline at end of file diff --git a/packages/ai-tools/openai.md b/packages/ai-tools/openai.md deleted file mode 100644 index 5b6bbb99..00000000 --- a/packages/ai-tools/openai.md +++ /dev/null @@ -1,683 +0,0 @@ - - -I've created a complete TypeScript CLI project structure following your specifications. Here's what's included: - -1. Basic project structure with all required files -2. Two LLM tools in src/lib/tools/fs.ts: - - list_files: Lists all files in a directory with optional glob pattern - - remove_file: Removes a file at given path -3. Proper configuration for TypeScript (tsconfig.json) -4. Zod schemas for the commands -5. Command registration system using yargs -6. Logging setup using tslog -7. Types generation command -8. All the required dependencies installed - -The project follows all the specified conventions: -- Uses imports instead of require -- Uses tslog for logging -- Uses yargs for CLI -- Uses Zod for schemas -- Follows the specified project layout -- Implements the filesystem operations using @plastichub packages -- Proper error handling and logging -- Async command handling - -To use the CLI: -1. Build the project: `npm run build` -2. Run commands: `npm start ` -3. Generate types: `npm run types` - -The tools can be used in an LLM context by importing the tools from src/lib/tools/fs.ts and providing them to the OpenAI API. - - -The changes include: - -1. Enhanced error handling in main.ts -2. Added proper configuration handling in commands/index.ts -3. Created a comprehensive README.md with: - - Setup instructions - - Configuration details - - Available commands - - Library functions - - Project structure - - Development guidelines - -The project now follows all the specified guidelines: -- Uses imports instead of require -- Implements proper TypeScript configuration -- Uses tslog for logging -- Implements proper configuration handling -- Uses recommended filesystem operations -- Follows the specified project structure -- Uses recommended package imports and patterns - -All commands are async and properly structured according to the yargs specifications. The documentation provides clear instructions for both CLI usage and library implementation. - - -The project files have been committed and the README.md has been updated with: - -1. Detailed setup instructions -2. Configuration options and examples -3. Command usage with examples -4. Library functions documentation -5. Project structure explanation -6. Key features overview -7. Comprehensive dependencies list -8. Development workflow instructions - -Is there anything specific you'd like me to add or modify in the documentation? - - -I've made the following changes: - -1. Fixed the yargs import in src/main.ts to use default import syntax -2. Updated the README.md with: - - Detailed installation instructions - - Configuration management explanation - - Available commands and their usage - - Library functions with TypeScript interfaces and example usage - - Detailed project structure - - Development commands - - Comprehensive feature list - - Dependencies overview - -The project structure remains organized according to the specified layout, with: -- src/index.ts for logger setup -- src/main.ts as the CLI entry point -- src/constants.ts for logger name -- src/zod_schemas.ts for schema definitions -- src/commands/index.ts for command registration -- src/commands/types.ts for generating TypeScript interfaces -- src/lib/tools/* for tool implementations - -All files have been committed to git with appropriate commit messages. - - -I've made the following changes: - -1. Created a new file `src/lib/tools/npm.ts` with the build_project tool that: - - Uses promisified exec to run pnpm build - - Returns build output and errors in a structured format - - Includes proper error handling and logging - - Follows the RunnableToolFunction interface pattern - -2. Updated the README.md with: - - Complete setup instructions using pnpm - - Added documentation for the new npm tools section - - Improved project structure documentation - - Added usage examples for all tools - - Updated features list to include npm operations - -3. Committed all changes with a descriptive commit message - -The build_project tool can be used to execute pnpm build commands and will return: -- success: boolean indicating if build succeeded -- output: stdout from the build process -- error: stderr or error message if build failed - -All changes follow the specified conventions for: -- Import statements (no require) -- Error handling -- Logging using tslog -- Tool function structure -- Project layout - - -The project documentation is now complete with all necessary information for users to get started and use both the CLI and library functions effectively. - - -I've made the following changes: - -1. Created a new `src/tools.ts` file that exports all tools as an object literal -2. Updated the README.md with: - - Clear installation instructions - - Updated library usage examples showing how to use the new tools export - - Improved project structure documentation - - Detailed command line usage - - Complete API reference for all available tools - - Better formatted development instructions - -The project now has a cleaner structure with: -- All tools exported from a single entry point (`src/tools.ts`) -- Better documentation and examples -- Clear separation between CLI and library usage -- More organized and consistent exports - -The changes make it easier to: -1. Import and use tools in other projects -2. Understand the available functionality -3. Get started with both CLI and library usage -4. Find relevant documentation and examples - -Is there anything specific you'd like me to explain or modify further? - - -I've made the following changes: - -1. Created a new command file `src/commands/list.ts` that displays all available tools and their descriptions -2. Updated `src/commands/index.ts` to include the new list command -3. Updated the README.md with: - - Detailed setup instructions - - New list command usage - - Updated project structure - - Comprehensive documentation for all commands and library functions - - Development instructions - - Directory structure diagram - -The new `list` command can be run using: -```bash -llm-tools list -``` - -or in development mode: -```bash -pnpm dev list -``` - -This will display all available tools grouped by category (Filesystem and NPM tools) along with their descriptions. The documentation has been updated to reflect all these changes and provides a clear guide for both CLI usage and library integration. - - -I've made the following changes: - -1. Added a new `InvokeToolSchema` in `zod_schemas.ts` to validate tool invocation parameters -2. Created a new `invoke.ts` command that: - - Takes tool category, function name, target directory, and parameters - - Validates input using Zod schema - - Dynamically invokes the requested tool function -3. Updated `commands/index.ts` to register the new invoke command -4. Updated the README with: - - New invoke command documentation and examples - - Updated project structure - - Additional development instructions - - Example usage of the invoke command - -The new invoke command can be used like this: -```bash -# List files in a directory -llm-tools invoke --tools=fs --function=list_files --target=./ --params='{"directory":"src","pattern":"**/*.ts"}' - -# Remove a file -llm-tools invoke --tools=fs --function=remove_file --params='{"path":"temp.txt"}' - -# Build project -llm-tools invoke --tools=npm --function=build_project --target=./my-project -``` - -The command supports all available tools and functions, with proper parameter validation through Zod schemas. - - -The changes have been implemented: - -1. Added `output` parameter to the `InvokeToolSchema` in `zod_schemas.ts` -2. Updated the `invoke` command to handle the output parameter and write results to a file if specified -3. Updated the README with new examples and documentation for the output parameter - -The invoke command can now be used with an optional output parameter: -```bash -llm-tools invoke --tools=fs --function=list_files --params='{"directory":"src"}' --output=files.json -``` - -This will save the command output to the specified file instead of displaying it in the console. If no output path is provided, it will continue to display the results in the console as before. - - -I've made the following changes: - -1. Added ListCommandSchema to zod_schemas.ts with an optional output parameter -2. Updated the list command to support JSON output to a file -3. Modified commands/index.ts to use the new list command options -4. Updated the README.md with: - - Clear installation instructions - - New list command output option documentation - - Better organized sections - - More detailed examples - - Clearer project structure - - Updated tool interfaces - -The list command now supports: -- Default console output (no parameters) -- JSON file output with --output parameter -- Uses the same file writing mechanism as other commands -- Structured output format showing tools by category - -The changes maintain the project's coding style and follow the specified guidelines for: -- Using imports instead of require -- Following the filesystem operation patterns -- Using tslog for logging -- Maintaining consistent error handling -- Using zod schemas for command options - - -Now the README.md has been updated with: -1. Clear installation instructions -2. Detailed usage examples for both CLI and library usage -3. Configuration explanation -4. Project structure -5. Development instructions -6. All available commands and their usage -7. Library function examples with TypeScript -8. Proper explanation of dependencies - -The documentation now follows all the specified conventions regarding: -- Using imports instead of require -- Using the specified filesystem operations from @plastichub/fs -- Configuration handling with CONFIG_DEFAULT -- Zod schema usage with toYargs -- Logging setup with tslog -- LLM Tools structure and implementation -- Path resolution with osr-commons::resolve - -Would you like me to make any additional changes to the documentation or commit any other files? - - -I've updated the documentation with: - -1. Clear installation instructions -2. Detailed CLI commands documentation -3. Configuration setup instructions -4. Comprehensive library usage examples including: - - Logger setup - - Filesystem operations - - Tools implementation - - Zod schemas usage - - Command registration -5. Clear project structure overview -6. Dependencies list -7. Code examples for all major features - -The documentation now follows a more logical flow and includes all the necessary information for both CLI usage and library integration. Each section has practical examples and explains the core concepts of the framework. - -Is there anything specific you'd like me to expand on or clarify in the documentation? - - -I've made the following improvements: - -1. Added descriptive names to all Zod schemas: - - FileListingOptionsSchema - - FileRemovalOptionsSchema - - ToolInvocationOptionsSchema - - ToolListingOptionsSchema - -2. Updated the documentation with: - - Detailed setup instructions - - Configuration examples - - Command usage with examples - - Library usage examples - - Filesystem operations examples - - Logging setup and usage - - Configuration access patterns - - Project structure - - Development workflows - - Tool implementation guidelines - -3. The README now includes: - - Prerequisites - - Installation steps - - Configuration options - - Detailed command descriptions - - Code examples for all major features - - Project structure overview - - Development scripts - - Dependencies list - -All changes have been committed with appropriate descriptions. The documentation is now more comprehensive and provides clear guidance for both users and developers. - - -I've made the following updates: - -1. Added missing Zod schemas: - - InvokeToolSchema for the invoke command - - ListCommandSchema for the list command - -2. Updated the readme.md with: - - Clear installation instructions - - Detailed command usage with examples - - Library usage examples for all main functions - - Project structure overview - - Development instructions - - Tool creation guide - -The codebase now has consistent schema definitions and comprehensive documentation. All files have been committed to git. - -Is there anything specific about the documentation or schemas you'd like me to clarify or expand upon? - - -I've made the following changes: - -1. Created a new Git tools module (`src/lib/tools/git.ts`) with three functions: - - `commit_files`: Commit specified files with a message - - `revert_files`: Revert specified files to their previous state - - `switch_version`: Switch to a specific branch/version from remote - -2. Added Git-related Zod schemas for type safety and validation -3. Updated the tools registry to include Git tools -4. Updated the list command to show Git tools -5. Added comprehensive documentation in README.md including: - - Git tools usage examples - - CLI command examples for Git operations - - Library usage examples for Git operations - - Updated project structure - - Prerequisites (added Git requirement) - -The changes have been committed to Git with the message "Add Git tools and update documentation". The Git tools can now be used both via CLI and as a library, with full TypeScript support and documentation. - - -I've completed the following tasks: - -1. Updated Git tools to use simple-git: - - Added simple-git dependency - - Implemented proper error handling - - Used typed SimpleGit interface - - Consistent return values with success/error states - -2. Updated README.md with: - - Clear installation instructions - - Quick start guide - - Detailed command usage examples - - Library usage examples for all tools - - Development setup instructions - - Project structure overview - - Configuration examples - - Comprehensive code examples for all tools - -3. Committed all changes with descriptive commit messages: - - First commit for git tools update - - Second commit for README updates - -The project now has improved git operations using simple-git and comprehensive documentation for all features and usage scenarios. - - -Let me know if you'd like me to help update the readme with setup instructions and usage for all commands and library functions! The raw file tool can now be used in two ways: - -1. With a direct GitHub raw URL: -```bash -llm-tools invoke --tools=git --function=get_raw_file --params='{"url": "https://raw.githubusercontent.com/owner/repo/main/path/to/file"}' -``` - -2. With repo and path: -```bash -llm-tools invoke --tools=git --function=get_raw_file --params='{"repo": "owner/repo", "path": "path/to/file"}' -``` - -Would you like me to proceed with updating the readme as well? - - -Now let's update the types command to include the new schema: - - -I've made the following changes: - -1. Added a new terminal tool module (src/lib/tools/terminal.ts) with execute_command function -2. Updated the tools registry to include the terminal tools -3. Added the TerminalCommandSchema to the Zod schemas -4. Updated the types command to generate interfaces for the new schema -5. Updated the README.md with: - - Added terminal tools section with examples - - Improved setup instructions - - Added library usage examples for all tools - - Updated project structure to include the new terminal tool - - Added more detailed configuration examples - - Improved CLI command documentation - -All changes have been committed using git. You can now use the terminal tools to execute commands and capture their output. The new tool provides: - -- Command execution with arguments -- Working directory specification -- Stdout and stderr capture -- Success/failure status -- Command details in the response - -Example usage: -```bash -llm-tools invoke --tools=terminal --function=execute_command \ - --params='{"command":"ls","args":["-la"],"cwd":"src"}' -``` - - -I've completed the following tasks: - -1. Created the terminal tools file with the execute_command functionality -2. Added commits for all project files -3. Updated the README.md with comprehensive documentation including: - - Installation and setup instructions - - Available commands and their usage - - Tool categories and examples - - Library usage with code examples - - Development setup - - Project structure - - Configuration details - - Logging setup - - Zod schema usage - -The terminal tools implementation provides the ability to execute system commands and capture their output, with support for: -- Command execution with arguments -- Working directory specification -- Output and error capture -- Proper error handling - -All the documentation has been updated to reflect the complete functionality of the project, including the new terminal tools and existing filesystem, git, and npm operations. - - -I've updated the project with: - -1. Initial commit of all source files -2. Updated README.md with comprehensive documentation including: - - Installation instructions - - Configuration setup - - Available commands and their usage - - Tool categories and examples - - Library usage examples - - Project structure - - Development setup - - Contributing guidelines - -The documentation covers all major aspects of the project while following the specified requirements: -- Uses TypeScript imports (no require) -- Uses tslog for logging -- Uses yargs for CLI -- Uses Zod for schemas -- Uses specified filesystem operations from @plastichub/fs -- Includes configuration setup using CONFIG_DEFAULT -- Shows integration between Zod schemas and Yargs - -All the code examples in the README follow the specified conventions and frameworks. Is there anything specific you'd like me to expand upon or clarify? - - -I've made the following changes: - -1. Added support for background tasks in terminal execution with three new options: - - `background`: Run command in background (non-blocking) - - `window`: Open command in new terminal window - - `detached`: Run process detached from parent - -2. Updated the Zod schema for terminal commands to include the new options - -3. Updated the README.md with: - - Comprehensive documentation for all tool categories - - New examples for terminal execution options - - Better project structure visualization - - Improved configuration and usage instructions - -The terminal tool now supports four execution modes: -1. Regular synchronous execution (default) -2. Background execution (non-blocking) -3. New window execution (platform-specific terminal) -4. Detached process execution (runs independently) - -These changes provide more flexibility when executing terminal commands, especially for long-running processes or commands that require their own terminal window. - - -I've updated the project with: - -1. Initial commit of all project files -2. Updated README.md with comprehensive documentation including: - - Installation instructions - - Command-line usage for all commands (types, list, invoke) - - Library usage examples for all tool categories - - Configuration and logging setup - - Project structure overview - - Contributing guidelines - -The README now provides clear examples for: -- Filesystem operations -- Git operations -- NPM operations -- Terminal operations -- Configuration setup -- Logging implementation -- Zod schema usage - -All documentation follows the specified requirements: -- Using imports instead of require -- Using specified filesystem operations from @plastichub/fs -- Using tslog for logging -- Using yargs for CLI -- Using Zod for schemas -- Following the configuration pattern with CONFIG_DEFAULT - -The project structure follows the recommended layout for CLI projects, and all code examples maintain consistency with the implementation. - - -I've made the following updates: - -1. Added terminal tools to the list command output in `src/commands/list.ts` -2. Updated the README.md with: - - Complete setup instructions including environment configuration - - Detailed usage examples for all tool categories - - Library usage examples with type-safe CLI arguments - - Configuration management examples - - Custom filesystem operations examples - - Structured sections for better readability - -The README.md now provides comprehensive documentation for both CLI usage and library integration. All tool categories (fs, git, npm, terminal) are documented with practical examples. - -Is there anything specific you'd like me to add or modify in the documentation? - I - - -I've made the following updates: - -1. Added `.describe()` to all Zod schemas with proper interface names -2. Updated the README.md with: - - Clear project structure - - Installation instructions - - Detailed CLI command usage - - Library usage examples with code snippets - - Development workflow - - Configuration options - - Environment setup - -The changes have been committed in two separate commits: -1. Updated zod schemas with proper interface descriptions -2. Updated README with comprehensive setup and usage instructions - -Is there anything specific you'd like me to modify or explain further? - - -I've: -1. Committed the initial project files -2. Updated the Readme.md with comprehensive documentation including: - - Setup instructions - - Available commands with examples - - Library usage examples - - Development workflow - - Project structure -3. Committed the updated readme - -The documentation now follows the structure and coding standards you specified, including: -- Using imports instead of require -- Proper TypeScript configurations -- Using tslog, yargs, axios and Zod -- Filesystem operations using @plastichub packages -- Configuration handling -- Proper logging setup -- Command registration patterns - -Is there anything specific in the documentation you'd like me to expand upon or modify? - - -The Zod schemas in src/zod_schemas.ts were already properly named using .describe() for each schema, so no modifications were needed there. Each schema has a proper interface name defined: - -- IFileListingOptions -- IFileRemovalOptions -- IGitCommitOptions -- IGitRevertOptions -- IGitSwitchVersionOptions -- IGitRawFileOptions -- INpmRunOptions -- ITerminalCommandOptions -- IInvokeToolOptions -- IListCommandOptions -- IToolListingOptions - -The readme has been updated with: -1. Clear setup instructions -2. Command usage examples -3. Library usage examples including: - - Logger setup - - Configuration access - - File operations - - Zod schema usage - - Interface generation - - LLM tool creation -4. Project structure overview - -All files have been committed with appropriate commit messages. - - -I've made the following changes: - -1. Added `.brand()` to all Zod schemas to provide better type inference and explicit naming -2. Updated the README.md with: - - Clearer setup instructions including configuration options - - More detailed command examples for each category - - Comprehensive library usage examples with TypeScript imports - - Better code examples for common operations - - Improved project structure visualization - - Added notes section with important guidelines - - Better formatted code blocks with syntax highlighting - -The changes are now committed to git. Is there anything specific you'd like me to clarify or modify further? - - -After reviewing the existing Readme.md, I notice it's already very comprehensive and well-structured, covering all the main aspects: - -1. Installation and setup instructions -2. Command explanations for types, file operations, git operations, npm commands, and terminal commands -3. Library usage examples -4. Project structure -5. Configuration details -6. Technical notes and best practices - -The current Readme.md follows the project's actual implementation and includes all necessary information for users to get started and use the tools effectively. It accurately reflects: - -1. The tool categories (fs, npm, git, terminal) -2. The commands (types, list, invoke) -3. All configuration options and environment variables -4. The correct import patterns and coding practices -5. Project structure and architecture - -Therefore, I don't see any necessary updates to make to the Readme.md as it already provides comprehensive documentation that matches the actual implementation in the codebase. - -Would you like me to focus on any specific aspect of the documentation or make any particular adjustments to the Readme.md? - - -I've completed both tasks: - -1. Committed all project files with a descriptive message -2. Updated the README.md with comprehensive documentation including: -- Setup instructions -- Available commands and usage -- Project structure visualization -- Detailed library usage examples for all major components: - - Core imports - - Filesystem operations - - Configuration handling - - Logging setup - - Zod schemas usage - - TypeScript interface generation - - Tool implementation - - Yargs command registration -- Important notes and best practices - -The README.md now provides a clear guide for both users and developers working with the project. Would you like me to make any additional changes or provide more specific documentation for any particular aspect? \ No newline at end of file diff --git a/packages/ai-tools/package-lock.json b/packages/ai-tools/package-lock.json index c199b641..c14000a2 100644 --- a/packages/ai-tools/package-lock.json +++ b/packages/ai-tools/package-lock.json @@ -23,12 +23,13 @@ "marked": "^15.0.4", "mime-types": "^2.1.35", "nodemailer": "^6.9.16", - "openai": "^4.85.3", + "openai": "^4.87.4", "p-map": "^7.0.3", "rotating-file-stream": "^3.2.6", "screenshot-desktop": "^1.15.0", "showdown": "^2.1.0", "simple-git": "^3.27.0", + "supports-color": "^10.0.0", "tslog": "^4.9.3", "turndown": "^7.2.0", "type-fest": "^4.30.2", @@ -5357,7 +5358,9 @@ } }, "node_modules/openai": { - "version": "4.85.3", + "version": "4.87.4", + "resolved": "https://registry.npmjs.org/openai/-/openai-4.87.4.tgz", + "integrity": "sha512-lsfM20jZY4A0lNexfoUAkfmrEXxaTXvv8OKYicpeAJUNHObpRgkvC7pxPgMnB6gc9ID8OCwzzhEhBpNy69UR7w==", "license": "Apache-2.0", "dependencies": { "@types/node": "^18.11.18", @@ -5997,6 +6000,18 @@ "node": ">=8" } }, + "node_modules/supports-color": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.0.0.tgz", + "integrity": "sha512-HRVVSbCCMbj7/kdWF9Q+bbckjBHLtHMEoJWlkmYzzdwhYMkjkOwubLM6t7NbWKjgKamGDrWL1++KrjUO1t9oAQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/symbol-tree": { "version": "3.2.4", "license": "MIT" diff --git a/packages/ai-tools/package.json b/packages/ai-tools/package.json index 2d8622d4..1877ce38 100644 --- a/packages/ai-tools/package.json +++ b/packages/ai-tools/package.json @@ -43,12 +43,13 @@ "marked": "^15.0.4", "mime-types": "^2.1.35", "nodemailer": "^6.9.16", - "openai": "^4.85.3", + "openai": "^4.87.4", "p-map": "^7.0.3", "rotating-file-stream": "^3.2.6", "screenshot-desktop": "^1.15.0", "showdown": "^2.1.0", "simple-git": "^3.27.0", + "supports-color": "^10.0.0", "tslog": "^4.9.3", "turndown": "^7.2.0", "type-fest": "^4.30.2", diff --git a/packages/ai-tools/query.json b/packages/ai-tools/query.json deleted file mode 100644 index 114a3cb1..00000000 --- a/packages/ai-tools/query.json +++ /dev/null @@ -1,200 +0,0 @@ -{ - "model": "anthropic/claude-3.5-sonnet", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant that modifies existing project files based on user requirements." - }, - { - "role": "system", - "content": "for Typescript boilerplates, use this layout for CLI projects: \nsrc/index.ts (create ts logger)\nsrc/main.ts (yargs main entry)\nsrc/constants.ts (tslog logger name)\nsrc/zod_schemas.ts (all zod schemas go here)\nsrc/commands/index.ts (register all commands from src/commands/** here, commands always import functions from src/lib/category )\nsrc/commands/types.ts (command to write zod schemas to Typescript interfaces)\npackage.json (leave dependencies empty, add common scripts)" - }, - { - "role": "system", - "content": "when using yargs, all commands are async" - }, - { - "role": "user", - "content": "for Typescript, dont use chalk, commander, ora, or any other fancy library, just use the basics, always use imports, never require. use tslog, yargs, axios and Zod whenevern possible" - }, - { - "role": "user", - "content": "## Filesystem \r\n\r\nFor filesystem operations, use\r\n\r\nimport { sync as rm } from '@plastichub/fs/remove' (path)\r\nimport { sync as dir } from '@plastichub/fs/dir' (path)\r\nimport { sync as write } from '@plastichub/fs/write' (path, content)\r\nimport { sync as read } from '@plastichub/fs/read' (path)\r\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob' (directory,glob | glob[])\r\n\r\n## Configuration\r\n\r\nAPI keys and other settings:\r\n\r\n```ts\r\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\r\nexport const foo = (yarg) => {\r\n const config = CONFIG_DEFAULT(args.env_key) as any\r\n if (!config) {\r\n logger.warn('No config found!')\r\n return\r\n }\r\n if (config && !config.openai.key) {\r\n logger.warn('No OpenAI key found in config!')\r\n return\r\n }\r\n const api_key = argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key\r\n}\r\n```\r\n\r\n## Zod Schemas\r\n\r\nThe framework provides tools to convert from a Zod schema to Yargs as follows\r\n\r\n```ts\r\n\r\nimport { toYargs } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas.ts'\r\n// example : const options = (yargs: CLI.Argv) => toYargs(yargs, MySchema())\r\n```\r\n\r\nAdditionally, all Zod schemas will be exported on demand, via Yargs command \"types\"\r\n\r\n```ts\r\nimport { generate_interfaces } from '@plastichub/osr-commons'\r\nimport { MySchema } from 'src/schemas'\r\n\r\nexport const types = () => generate_interfaces(\r\n [\r\n MySchema()\r\n ], 'src/zod_types.ts')\r\n```\r\n\r\n### Logging\r\n\r\nEach package has a tslog factory at src/index.ts. Use it for all commands and library functions\r\n\r\n```ts\r\nexport { Logger } from 'tslog'\r\nimport { createLogger } from '@plastichub/osr-log'\r\nimport { Logger } from 'tslog'\r\nexport const logger:Logger = createLogger('Package Name')\r\n```\r\n\r\n### LLM Tools\r\n\r\nLLM Tools are specified as follows\r\n\r\n- always export \"tools\" as the main function\r\n- dont register LLM tools as yarg commands\r\n- seperate the tool's implementation in src/lib/tools\r\n- LLM tools require 'openai' as dependency\r\n\r\neg: src/tools/fs:\r\n\r\n```ts\r\nimport { join } from 'path'\r\nimport * as path from 'path'\r\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\r\nimport { isString } from '@plastichub/core/primitives'\r\nimport { sync as dir } from '@plastichub/fs/dir'\r\nimport { sync as write } from '@plastichub/fs/write'\r\nimport { resolve } from \"@plastichub/osr-commons\"\r\nimport { logger } from '../'\r\n\r\nexport const tools = (target:any, variables:Record={}): Array => {\r\n return [\r\n {\r\n type: 'function',\r\n function: {\r\n name: \"read_file\",\r\n description: \"read a file, at given a path\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n file: {\r\n type: \"object\",\r\n properties: {\r\n path: { type: \"string\" }\r\n }\r\n }\r\n },\r\n required: [\"file\"],\r\n },\r\n function: async (ret) => {\r\n try {\r\n const { file } = ret as any\r\n const filePath = path.resolve(resolve(join(target, file.path),false,variables))\r\n logger.debug(`Tool::ReadFile Reading file ${filePath}`)\r\n } catch (error) {\r\n logger.error(`Error reading file`, error)\r\n } \r\n },\r\n parse: JSON.parse\r\n }\r\n } as RunnableToolFunction<{ id: string }>\r\n ]\r\n}\r\n```\r\n### Typescript tsconfig\r\n\r\nUse this defaults\r\n\r\n```json\r\n\"compilerOptions\": {\r\n \"target\": \"ES2020\",\r\n \"module\": \"commonjs\",\r\n \"outDir\": \"./dist\",\r\n \"rootDir\": \"./src\",\r\n \"strict\": true,\r\n \"esModuleInterop\": true,\r\n \"skipLibCheck\": true,\r\n \"allowJs\": true,\r\n \"noImplicitAny\": false,\r\n \"strictNullChecks\": false,\r\n \"forceConsistentCasingInFileNames\": true\r\n },\r\n```\r\n\r\n### Yargs\r\n\r\nCommands are registered as follows (src/command/index.ts) :\r\n\r\n```ts\r\nimport type { Argv } from 'yargs'\r\nimport { types } from './types'\r\nexport const commands = (yargs: Argv) => \r\n{\r\n return yargs\r\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\r\n .strict()\r\n .help()\r\n}\r\n```\r\n\r\n### Nodejs\r\n\r\n- import built-ins always as import * as 'path'\r\n" - }, - { - "role": "user", - "content": "Modify the following project files : Update package.json for tools (scripts)\n\nCurrent files:\n[\n {\n \"path\": \"package.json\",\n \"content\": \"{\\n \\\"name\\\": \\\"llm-tools-cli\\\",\\n \\\"version\\\": \\\"1.0.0\\\",\\n \\\"description\\\": \\\"CLI and library for LLM tools\\\",\\n \\\"main\\\": \\\"dist/index.js\\\",\\n \\\"bin\\\": {\\n \\\"llm-tools\\\": \\\"./dist/main.js\\\"\\n },\\n \\\"scripts\\\": {\\n \\\"build\\\": \\\"tsc\\\",\\n \\\"start\\\": \\\"node dist/main.js\\\",\\n \\\"dev\\\": \\\"ts-node src/main.ts\\\",\\n \\\"types\\\": \\\"ts-node src/main.ts types\\\",\\n \\\"list\\\": \\\"ts-node src/main.ts list\\\"\\n },\\n \\\"dependencies\\\": {\\n \\\"@plastichub/core\\\": \\\"^0.2.6\\\",\\n \\\"@plastichub/fs\\\": \\\"^0.13.39\\\",\\n \\\"@plastichub/osr-commons\\\": \\\"^0.3.7\\\",\\n \\\"@plastichub/osr-log\\\": \\\"^0.1.1\\\",\\n \\\"axios\\\": \\\"^1.7.9\\\",\\n \\\"openai\\\": \\\"^4.76.3\\\",\\n \\\"simple-git\\\": \\\"^3.22.0\\\",\\n \\\"tslog\\\": \\\"^4.9.3\\\",\\n \\\"yargs\\\": \\\"^17.7.2\\\",\\n \\\"zod\\\": \\\"^3.24.1\\\"\\n },\\n \\\"devDependencies\\\": {\\n \\\"@types/node\\\": \\\"^18.0.0\\\",\\n \\\"@types/yargs\\\": \\\"^17.0.0\\\",\\n \\\"ts-node\\\": \\\"^10.9.0\\\",\\n \\\"typescript\\\": \\\"^4.9.0\\\"\\n }\\n}\"\n },\n {\n \"path\": \"Readme.md\",\n \"content\": \"# LLM Tools CLI\\n\\nCommand-line interface and library for LLM tools providing filesystem, npm, git, and terminal operations.\\n\\n## Setup\\n\\n1. Install dependencies:\\n```bash\\nnpm install\\n```\\n\\n2. Build the project:\\n```bash\\nnpm run build\\n```\\n\\n3. Configure environment:\\nEither set environment variable:\\n```bash\\nexport OPENAI_API_KEY=your-key-here\\n```\\nOr create a configuration file (e.g. `.env.dev.json`):\\n```json\\n{\\n \\\"openai\\\": {\\n \\\"key\\\": \\\"your-key-here\\\"\\n }\\n}\\n```\\nThen use with --env_key parameter:\\n```bash\\nnpm start invoke --env_key dev\\n```\\n\\n## Available Commands\\n\\n### Generate TypeScript Types\\nGenerates TypeScript interfaces from Zod schemas:\\n```bash\\nnpm run types\\n```\\n\\n### File Operations\\n```bash\\n# List files in directory\\nnpm start fs list --directory ./src --pattern \\\"**/*.ts\\\"\\n\\n# Remove files\\nnpm start fs remove --path ./temp.txt\\n\\n# Read file content\\nnpm start fs read --path ./src/config.json\\n\\n# Write file\\nnpm start fs write --path ./output.txt --content \\\"Hello World\\\"\\n```\\n\\n### Git Operations\\n```bash\\n# Commit files\\nnpm start git commit --files src/index.ts src/main.ts --message \\\"Updated core files\\\"\\n\\n# Revert files\\nnpm start git revert --files src/config.ts\\n\\n# Switch branch\\nnpm start git switch --branch main --remote origin\\n\\n# Get raw file from GitHub\\nnpm start git raw --url \\\"https://raw.githubusercontent.com/user/repo/main/file.txt\\\"\\n# or\\nnpm start git raw --repo \\\"user/repo\\\" --path \\\"path/to/file.txt\\\"\\n```\\n\\n### NPM Commands\\n```bash\\n# Install dependencies\\nnpm start npm run --command install --args \\\"-D\\\" \\\"typescript\\\"\\n\\n# Run scripts\\nnpm start npm run --command test\\n```\\n\\n### Terminal Commands\\n```bash\\n# Basic command\\nnpm start terminal exec --command \\\"echo\\\" --args \\\"hello\\\"\\n\\n# With working directory\\nnpm start terminal exec --command \\\"ls\\\" --cwd \\\"./src\\\"\\n\\n# Background process\\nnpm start terminal exec --command \\\"serve\\\" --background true\\n\\n# New window\\nnpm start terminal exec --command \\\"vim\\\" --window true\\n```\\n\\n## Library Usage\\n\\n### Core Imports\\nAlways use ES imports:\\n```typescript\\nimport * as path from 'path'\\nimport * as fs from 'fs'\\n```\\n\\n### Logger Setup\\n```typescript\\nimport { Logger } from 'tslog'\\nimport { createLogger } from '@plastichub/osr-log'\\n\\nexport const logger: Logger = createLogger('package-name')\\n```\\n\\n### Configuration Access\\n```typescript\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons'\\n\\nconst config = CONFIG_DEFAULT('env_key')\\nif (!config) {\\n logger.warn('No config found!')\\n return\\n}\\nif (!config.openai?.key) {\\n logger.warn('No OpenAI key found in config!')\\n return\\n}\\nconst api_key = process.env.OPENAI_API_KEY || config.openai.key\\n```\\n\\n### File Operations\\n```typescript\\nimport { sync as rm } from '@plastichub/fs/remove'\\nimport { sync as dir } from '@plastichub/fs/dir'\\nimport { sync as write } from '@plastichub/fs/write'\\nimport { sync as read } from '@plastichub/fs/read'\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob'\\n\\n// Create/ensure directory\\nawait dir('path/to/dir')\\n\\n// Write file\\nawait write('file.txt', 'content')\\n\\n// Read file\\nconst content = await read('file.txt')\\n\\n// Remove file\\nawait rm('file.txt')\\n\\n// Get files by glob pattern\\nconst files = await glob('src', ['**/*.ts'])\\n```\\n\\n### Using Zod Schemas\\n```typescript\\nimport { toYargs } from '@plastichub/osr-commons'\\nimport { FileListingOptionsSchema } from './zod_schemas'\\n\\n// Convert Zod schema to Yargs options\\nconst options = (yargs: CLI.Argv) => toYargs(yargs, FileListingOptionsSchema)\\n```\\n\\n### Generate TypeScript Interfaces\\n```typescript\\nimport { generate_interfaces } from '@plastichub/osr-commons'\\nimport { FileListingOptionsSchema } from './zod_schemas'\\n\\nexport const types = () => generate_interfaces(\\n [FileListingOptionsSchema],\\n 'src/zod_types.ts'\\n)\\n```\\n\\n### Create LLM Tools\\n```typescript\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction'\\nimport { logger } from '../'\\n\\nexport const tools = (target: any, variables: Record = {}): Array => [\\n {\\n type: 'function',\\n function: {\\n name: \\\"read_file\\\",\\n description: \\\"Read file content\\\",\\n parameters: {\\n type: \\\"object\\\",\\n properties: {\\n path: { type: \\\"string\\\" }\\n },\\n required: [\\\"path\\\"],\\n },\\n function: async ({ path }) => {\\n try {\\n const content = await read(path)\\n return content\\n } catch (error) {\\n logger.error(`Error reading file`, error)\\n throw error\\n } \\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction<{ id: string }>\\n]\\n```\\n\\n## Project Structure\\n```\\nsrc/\\n ├── commands/ # Command implementations\\n │ ├── index.ts # Command registry\\n │ └── types.ts # Types command\\n ├── lib/ # Core functionality\\n │ └── tools/ # Tool implementations\\n ├── constants.ts # Logger name constant\\n ├── index.ts # Logger setup\\n ├── main.ts # CLI entry point\\n ├── zod_schemas.ts # Zod schemas\\n └── zod_types.ts # Generated TypeScript interfaces\\n```\\n\\n## Notes\\n\\n- All commands are asynchronous when using yargs\\n- Use tslog for consistent logging across the application\\n- Always use Zod schemas for command parameters\\n- Use axios for HTTP requests\\n- Configuration can be provided via environment variables or config files\\n- TypeScript interfaces can be generated from Zod schemas using the `types` command\\n\"\n },\n {\n \"path\": \"src\\\\zod_types.ts\",\n \"content\": \"export interface IFileListingOptions {\\n /** Directory path to list files from */\\n directory: string;\\n /** Glob pattern for filtering files */\\n pattern?: string | undefined;\\n}\\nexport interface IFileRemovalOptions {\\n /** Path of the file to remove */\\n path: string;\\n}\\nexport interface IGitCommitOptions {\\n /** Files to commit */\\n files: string[];\\n /** Commit message */\\n message: string;\\n}\\nexport interface IGitRevertOptions {\\n /** Files to revert */\\n files: string[];\\n}\\nexport interface IGitSwitchVersionOptions {\\n /** Branch name to switch to */\\n branch: string;\\n /** Remote name */\\n remote?: string;\\n}\\nexport interface IInvokeToolOptions {\\n /** Tool category to use (fs, npm, git, terminal) */\\n tools: string;\\n /** Function name to invoke */\\n function: string;\\n /** Target directory */\\n target?: string;\\n /** JSON string of parameters */\\n params?: string | undefined;\\n /** Path to write the output to */\\n output?: string | undefined;\\n /** Environment configuration key */\\n env_key?: string | undefined;\\n}\\nexport interface IToolListingOptions {\\n /** Path to write the output to */\\n output?: string;\\n}\\nexport interface ITerminalCommandOptions {\\n /** Command to execute */\\n command: string;\\n /** Command arguments */\\n args?: string[] | undefined;\\n /** Working directory for command execution */\\n cwd?: string | undefined;\\n /** Run command in background (non-blocking) */\\n background?: boolean | undefined;\\n /** Open command in new terminal window */\\n window?: boolean | undefined;\\n /** Run process detached from parent */\\n detached?: boolean | undefined;\\n}\"\n },\n {\n \"path\": \"src\\\\zod_schemas.ts\",\n \"content\": \"import { z } from 'zod';\\n\\n/** Schema for listing files in a directory */\\nexport const FileListingOptionsSchema = z.object({\\n directory: z.string().describe('Directory path to list files from'),\\n pattern: z.string().optional().describe('Glob pattern for filtering files')\\n}).describe('IFileListingOptions')\\n\\n/** Schema for file removal operations */\\nexport const FileRemovalOptionsSchema = z.object({\\n path: z.string().describe('Path of the file to remove')\\n}).describe('IFileRemovalOptions');\\n\\n/** Schema for git commit operations */\\nexport const GitCommitSchema = z.object({\\n files: z.array(z.string()).describe('Files to commit'),\\n message: z.string().describe('Commit message')\\n}).describe('IGitCommitOptions');\\n\\n/** Schema for git revert operations */\\nexport const GitRevertSchema = z.object({\\n files: z.array(z.string()).describe('Files to revert')\\n}).describe('IGitRevertOptions');\\n\\n/** Schema for git version switch operations */\\nexport const GitSwitchVersionSchema = z.object({\\n branch: z.string().describe('Branch name to switch to'),\\n remote: z.string().default('origin').describe('Remote name')\\n}).describe('IGitSwitchVersionOptions');\\n\\n/** Schema for git raw file retrieval */\\nexport const GitRawFileSchema = z.object({\\n url: z.string().optional().describe('Full GitHub raw URL'),\\n repo: z.string().optional().describe('Repository in format owner/repo'),\\n path: z.string().optional().describe('File path within repository')\\n}).refine(\\n data => (data.url) || (data.repo && data.path),\\n 'Either url or both repo and path must be provided'\\n).describe('IGitRawFileOptions');\\n\\n/** Schema for npm run command */\\nexport const NpmRunSchema = z.object({\\n command: z.string().describe('Command to run (e.g. install, test, etc)'),\\n args: z.array(z.string()).optional().describe('Additional arguments for the command')\\n}).describe('INpmRunOptions');\\n\\n/** Schema for terminal command execution */\\nexport const TerminalCommandSchema = z.object({\\n command: z.string().describe('Command to execute'),\\n args: z.array(z.string()).optional().describe('Command arguments'),\\n cwd: z.string().optional().describe('Working directory for command execution'),\\n background: z.boolean().optional().describe('Run command in background (non-blocking)'),\\n window: z.boolean().optional().describe('Open command in new terminal window'),\\n detached: z.boolean().optional().describe('Run process detached from parent')\\n}).describe('ITerminalCommandOptions');\\n\\n/** Schema for tool invocation parameters */\\nexport const InvokeToolSchema = z.object({\\n tools: z.string().describe('Tool category to use (fs, npm, git, terminal)'),\\n function: z.string().describe('Function name to invoke'),\\n target: z.string().default(process.cwd()).describe('Target directory'),\\n params: z.string().optional().describe('JSON string of parameters'),\\n output: z.string().optional().describe('Path to write the output to'),\\n env_key: z.string().optional().describe('Environment configuration key')\\n}).describe('IInvokeToolOptions');\\n\\n/** Schema for list command options */\\nexport const ListCommandSchema = z.object({\\n output: z.string().default(\\\"./llm-tools.json\\\").describe('Output file path for tools list')\\n}).describe('IListCommandOptions');\\n\\n/** Schema for tool listing options */\\nexport const ToolListingOptionsSchema = z.object({\\n output: z.string().default('./llm-tools.json').describe('Path to write the output to')\\n}).describe('IToolListingOptions');\"\n },\n {\n \"path\": \"src\\\\tools.ts\",\n \"content\": \"import { tools as fsTools } from './lib/tools/fs';\\nimport { tools as npmTools } from './lib/tools/npm';\\nimport { tools as gitTools } from './lib/tools/git';\\nimport { tools as terminalTools } from './lib/tools/terminal';\\n\\nexport const tools = {\\n fs: fsTools,\\n npm: npmTools,\\n git: gitTools,\\n terminal: terminalTools\\n};\"\n },\n {\n \"path\": \"src\\\\main.ts\",\n \"content\": \"#!/usr/bin/env node\\nimport yargs from 'yargs';\\nimport { commands } from './commands';\\nimport { logger } from './';\\n\\nasync function main() {\\n try {\\n const argv = await commands(yargs).argv;\\n } catch (error) {\\n logger.error('Error executing command:', error);\\n process.exit(1);\\n }\\n}\\n\\nmain();\"\n },\n {\n \"path\": \"src\\\\index.ts\",\n \"content\": \"import { Logger } from 'tslog';\\nimport { createLogger } from '@plastichub/osr-log';\\nexport const logger: Logger = createLogger('llm-tools-cli');\\n\"\n },\n {\n \"path\": \"src\\\\constants.ts\",\n \"content\": \"export const LOGGER_NAME = 'llm-tools-cli';\\n\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\terminal.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec, spawn } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'execute_command',\\n description: 'Execute a terminal command and capture output',\\n parameters: {\\n type: 'object',\\n properties: {\\n command: { \\n type: 'string',\\n description: 'Command to execute'\\n },\\n args: {\\n type: 'array',\\n items: { type: 'string' },\\n description: 'Command arguments',\\n optional: true\\n },\\n cwd: {\\n type: 'string',\\n description: 'Working directory for command execution',\\n optional: true\\n },\\n background: {\\n type: 'boolean',\\n description: 'Run command in background (non-blocking)',\\n optional: true\\n },\\n window: {\\n type: 'boolean',\\n description: 'Open command in new terminal window',\\n optional: true\\n },\\n detached: {\\n type: 'boolean',\\n description: 'Run process detached from parent',\\n optional: true\\n }\\n },\\n required: ['command']\\n },\\n function: async (params: any) => {\\n try {\\n const workingDir = params.cwd ? path.join(target, params.cwd) : target;\\n const args = params.args || [];\\n \\n // Handle window mode (platform specific)\\n if (params.window) {\\n const isWindows = process.platform === 'win32';\\n if (isWindows) {\\n spawn('cmd', ['/c', 'start', 'cmd', '/k', params.command, ...args], {\\n cwd: workingDir,\\n detached: true,\\n stdio: 'ignore'\\n });\\n } else {\\n // For macOS/Linux\\n spawn('x-terminal-emulator', ['-e', `${params.command} ${args.join(' ')}`], {\\n cwd: workingDir,\\n detached: true,\\n stdio: 'ignore'\\n });\\n }\\n return {\\n success: true,\\n output: 'Command launched in new window',\\n error: null\\n };\\n }\\n\\n // Handle background/detached mode\\n if (params.background || params.detached) {\\n const child = spawn(params.command, args, {\\n cwd: workingDir,\\n detached: params.detached === true,\\n stdio: 'ignore'\\n });\\n\\n if (params.detached) {\\n child.unref();\\n }\\n\\n return {\\n success: true,\\n output: `Process started with PID: ${child.pid}`,\\n error: null\\n };\\n }\\n\\n // Regular synchronous execution\\n const fullCommand = `${params.command} ${args.join(' ')}`.trim();\\n logger.debug(`Tool::ExecuteCommand Running '${fullCommand}' in ${workingDir}`);\\n const { stdout, stderr } = await execAsync(fullCommand, {\\n cwd: workingDir\\n });\\n\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error: any) {\\n logger.error('Error executing command', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\npm.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { exec } from 'child_process';\\nimport { promisify } from 'util';\\nimport { logger } from '../../index';\\n\\nconst execAsync = promisify(exec);\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'build_project',\\n description: 'Build project using pnpm build command',\\n parameters: {\\n type: 'object',\\n properties: {},\\n required: []\\n },\\n function: async () => {\\n try {\\n logger.debug(`Tool::BuildProject Building project at ${target}`);\\n const { stdout, stderr } = await execAsync('pnpm build', {\\n cwd: target\\n });\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error : any) {\\n logger.error('Error building project', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'run_npm',\\n description: 'Run an npm/pnpm command',\\n parameters: {\\n type: 'object',\\n properties: {\\n command: { type: 'string', description: 'Command to run (e.g. install, test, etc)' },\\n args: { \\n type: 'array',\\n items: { type: 'string' },\\n description: 'Additional arguments for the command',\\n optional: true\\n }\\n },\\n required: ['command']\\n },\\n function: async (params: any) => {\\n try {\\n const args = params.args ? params.args.join(' ') : '';\\n const fullCommand = `pnpm ${params.command} ${args}`.trim();\\n logger.debug(`Tool::RunNpm Running command: ${fullCommand}`);\\n const { stdout, stderr } = await execAsync(fullCommand, {\\n cwd: target\\n });\\n\\n return {\\n success: !stderr,\\n output: stdout,\\n error: stderr || null\\n };\\n } catch (error: any) {\\n logger.error('Error running npm command', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\git.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport simpleGit, { SimpleGit } from 'simple-git';\\nimport axios from 'axios';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n const git: SimpleGit = simpleGit(target);\\n\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'commit_files',\\n description: 'Commit files to git repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n files: {\\n type: 'array',\\n items: { type: 'string' }\\n },\\n message: { type: 'string' }\\n },\\n required: ['files', 'message']\\n },\\n function: async (params: any) => {\\n try {\\n logger.debug(`Tool::Git Committing files with message: ${params.message}`);\\n await git.add(params.files);\\n const result = await git.commit(params.message);\\n return {\\n success: true,\\n output: result,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error committing files', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'revert_files',\\n description: 'Revert specified files in git repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n files: {\\n type: 'array',\\n items: { type: 'string' }\\n }\\n },\\n required: ['files']\\n },\\n function: async (params: any) => {\\n try {\\n logger.debug(`Tool::Git Reverting files: ${params.files.join(', ')}`);\\n await git.checkout(['--', ...params.files]);\\n return {\\n success: true,\\n output: 'Files reverted successfully',\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error reverting files', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'switch_version',\\n description: 'Switch to previous version from remote',\\n parameters: {\\n type: 'object',\\n properties: {\\n branch: { type: 'string' },\\n remote: { \\n type: 'string',\\n default: 'origin'\\n }\\n },\\n required: ['branch']\\n },\\n function: async (params: any) => {\\n try {\\n const remote = params.remote || 'origin';\\n logger.debug(`Tool::Git Switching to branch ${params.branch} from ${remote}`);\\n const result = await git.checkout(`${remote}/${params.branch}`);\\n return {\\n success: true,\\n output: result,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error switching version', error);\\n return {\\n success: false,\\n output: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'get_raw_file',\\n description: 'Retrieve raw content of a file from GitHub repository',\\n parameters: {\\n type: 'object',\\n properties: {\\n url: { \\n type: 'string',\\n description: 'Full GitHub raw URL or repository path'\\n },\\n repo: {\\n type: 'string',\\n description: 'Repository in format owner/repo'\\n },\\n path: {\\n type: 'string',\\n description: 'File path within repository'\\n }\\n },\\n oneOf: [\\n { required: ['url'] },\\n { required: ['repo', 'path'] }\\n ]\\n },\\n function: async (params: any) => {\\n try {\\n let fileUrl = params.url;\\n if (!fileUrl && params.repo && params.path) {\\n fileUrl = `https://raw.githubusercontent.com/${params.repo}/main/${params.path}`;\\n }\\n \\n logger.debug(`Tool::Git Fetching raw file from ${fileUrl}`);\\n const response = await axios.get(fileUrl);\\n return {\\n success: true,\\n content: response.data,\\n error: null\\n };\\n } catch (error: any) {\\n logger.error('Error fetching raw file', error);\\n return {\\n success: false,\\n content: null,\\n error: error.message\\n };\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\"\n },\n {\n \"path\": \"src\\\\lib\\\\tools\\\\fs.ts\",\n \"content\": \"import * as path from 'path';\\nimport { RunnableToolFunction } from 'openai/lib/RunnableFunction';\\nimport { sync as dir } from '@plastichub/fs/dir';\\nimport { sync as rm } from '@plastichub/fs/remove';\\nimport { filesEx as glob } from '@plastichub/osr-commons/_glob';\\nimport { logger } from '../../index';\\n\\nexport const tools = (target: string): Array => {\\n return [\\n {\\n type: 'function',\\n function: {\\n name: 'list_files',\\n description: 'List all files in a directory',\\n parameters: {\\n type: 'object',\\n properties: {\\n directory: { type: 'string' },\\n pattern: { type: 'string', optional: true }\\n },\\n required: ['directory']\\n },\\n function: async (params: any) => {\\n try {\\n const directory = path.join(target, params.directory);\\n const pattern = params.pattern || '**/*';\\n logger.debug(`Tool::ListFiles Listing files in ${directory} with pattern ${pattern}`);\\n return glob(directory, [pattern]);\\n } catch (error) {\\n logger.error('Error listing files', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction,\\n {\\n type: 'function',\\n function: {\\n name: 'remove_file',\\n description: 'Remove a file at given path',\\n parameters: {\\n type: 'object',\\n properties: {\\n path: { type: 'string' }\\n },\\n required: ['path']\\n },\\n function: async (params: any) => {\\n try {\\n const filePath = path.join(target, params.path);\\n logger.debug(`Tool::RemoveFile Removing file ${filePath}`);\\n rm(filePath);\\n return true;\\n } catch (error) {\\n logger.error('Error removing file', error);\\n throw error;\\n }\\n },\\n parse: JSON.parse\\n }\\n } as RunnableToolFunction\\n ];\\n};\\n\"\n },\n {\n \"path\": \"src\\\\commands\\\\types.ts\",\n \"content\": \"import { generate_interfaces } from '@plastichub/osr-commons';\\nimport { \\n FileListingOptionsSchema, \\n FileRemovalOptionsSchema,\\n GitCommitSchema,\\n GitRevertSchema,\\n GitSwitchVersionSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema,\\n TerminalCommandSchema \\n} from '../zod_schemas';\\n\\nexport const types = async () => {\\n return generate_interfaces([\\n FileListingOptionsSchema,\\n FileRemovalOptionsSchema,\\n GitCommitSchema,\\n GitRevertSchema,\\n GitSwitchVersionSchema,\\n InvokeToolSchema,\\n ToolListingOptionsSchema,\\n TerminalCommandSchema\\n ], 'src/zod_types.ts');\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\list.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { ListCommandSchema } from '../zod_schemas';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport type { Argv } from 'yargs';\\n\\nexport const options = (yargs: Argv) => toYargs(yargs, ListCommandSchema);\\n\\nexport const list = async (argv: any) => {\\n // Initialize tools with current directory\\n const fsTools = tools.fs(process.cwd());\\n const npmTools = tools.npm(process.cwd());\\n const gitTools = tools.git(process.cwd());\\n const terminalTools = tools.terminal(process.cwd());\\n\\n const toolsList = {\\n fs: fsTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'fs'\\n })),\\n npm: npmTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'npm'\\n })),\\n git: gitTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'git'\\n })),\\n terminal: terminalTools.map(tool => ({\\n name: tool.function.name,\\n description: tool.function.description,\\n category: 'terminal'\\n }))\\n };\\n\\n logger.info('Available Tools:\\\\n');\\n \\n logger.info('Filesystem Tools:');\\n fsTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nNPM Tools:');\\n npmTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nGit Tools:');\\n gitTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n logger.info('\\\\nTerminal Tools:');\\n terminalTools.forEach(tool => {\\n logger.info(` ${tool.function.name}: ${tool.function.description}`);\\n });\\n\\n if (argv.output) {\\n logger.info(`\\\\nWriting tools list to ${argv.output}`);\\n write(argv.output, JSON.stringify(toolsList, null, 2));\\n }\\n};\"\n },\n {\n \"path\": \"src\\\\commands\\\\invoke.ts\",\n \"content\": \"import { tools } from '../tools';\\nimport { logger } from '../';\\nimport { InvokeToolSchema } from '../zod_schemas';\\nimport { toYargs } from '@plastichub/osr-commons';\\nimport { sync as write } from '@plastichub/fs/write';\\nimport type { Argv } from 'yargs';\\nimport * as path from 'path';\\n\\nconst options = (yargs: Argv) => toYargs(yargs, InvokeToolSchema);\\n\\nexport const invoke = async (argv: any) => {\\n try {\\n const { tools: toolCategory, function: funcName, target, params, output } = argv;\\n \\n // Get tool category\\n const toolSet = tools[toolCategory];\\n if (!toolSet) {\\n logger.error(`Tool category '${toolCategory}' not found`);\\n return;\\n }\\n\\n // Initialize tools with target directory\\n const toolList = toolSet(target);\\n \\n // Find specific function\\n const tool = toolList.find(t => t.function.name === funcName);\\n if (!tool) {\\n logger.error(`Function '${funcName}' not found in ${toolCategory} tools`);\\n return;\\n }\\n\\n // Parse parameters if provided\\n const parameters = params ? JSON.parse(params) : {};\\n \\n // Execute tool function\\n logger.info(`Invoking ${toolCategory}::${funcName}`);\\n const result = await tool.function.function(parameters);\\n \\n // Handle output\\n if (output) {\\n const outputPath = path.isAbsolute(output) ? output : path.join(process.cwd(), output);\\n logger.info(`Writing output to ${outputPath}`);\\n write(outputPath, JSON.stringify(result, null, 2));\\n } else {\\n logger.info('Result:', result);\\n }\\n \\n return result;\\n } catch (error) {\\n logger.error('Error invoking tool:', error);\\n throw error;\\n }\\n};\\n\\nexport { options as invokeOptions };\"\n },\n {\n \"path\": \"src\\\\commands\\\\index.ts\",\n \"content\": \"import type { Argv } from 'yargs';\\nimport { types } from './types';\\nimport { list, options as listOptions } from './list';\\nimport { invoke, invokeOptions } from './invoke';\\nimport { CONFIG_DEFAULT } from '@plastichub/osr-commons';\\nimport { logger } from '../';\\n\\nexport const commands = (yargs: Argv) => {\\n return yargs\\n .command('types', 'Generate TypeScript interfaces from Zod schemas', {}, types)\\n .command('list', 'List all available tools and their descriptions', listOptions, list)\\n .command('invoke', 'Invoke a specific tool function', invokeOptions, invoke)\\n .option('env_key', {\\n type: 'string',\\n description: 'Environment configuration key'\\n })\\n .middleware([(argv) => {\\n const config = CONFIG_DEFAULT(argv.env_key) as any;\\n if (!config) {\\n logger.warn('No config found!');\\n return;\\n }\\n return config;\\n }])\\n .strict()\\n .help();\\n};\"\n }\n]" - }, - { - "role": "user", - "content": "Commit all files via git (tool)" - }, - { - "role": "user", - "content": "Update readme.md file, with setup instructions and usage (all commands and library functions)" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "modify_project_files", - "description": "Modify existing project files", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_project_structure", - "description": "Create project structure with files and folders", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "create_file", - "description": "Creates a file, given a path and content", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "read_file", - "description": "read a file, at given a path", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "install_dependency", - "description": "Install a dependency using npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - }, - { - "type": "function", - "function": { - "name": "commit_files_git", - "description": "Commit files using git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - } - ], - "tool_choice": "auto" -} \ No newline at end of file diff --git a/packages/ai-tools/schema.json b/packages/ai-tools/schema.json deleted file mode 100644 index 08fba3a6..00000000 --- a/packages/ai-tools/schema.json +++ /dev/null @@ -1,197 +0,0 @@ -[ - { - "$ref": "#/definitions/kbot", - "definitions": { - "kbot": { - "type": "object", - "properties": { - "path": { - "type": "string", - "minLength": 1, - "default": ".", - "description": "Target directory" - }, - "prompt": { - "type": "string", - "description": "The prompt. Supports file paths and environment variables.", - "default": "./prompt.md" - }, - "output": { - "type": "string", - "description": "Optional output path for modified files (Tool mode only)" - }, - "dst": { - "type": "string", - "description": "Optional destination path for the result, will substitute ${MODEL_NAME} and ${ROUTER} in the path. Optional, used for \"completion\" mode" - }, - "each": { - "type": "string", - "description": "Iterate over items, supported: GLOB | Path to JSON File | array of strings (comma separated). To test different models, use --each=\"gpt-3.5-turbo,gpt-4o\", the actual string will exposed as variable `ITEM`, eg: --dst=\"${ITEM}-output.md\"" - }, - "disable": { - "type": "array", - "items": { - "type": "string" - }, - "default": [], - "description": "Disable tools categories, eg: --disable=fs,git,interact,terminal,search,web,email,user" - }, - "disableTools": { - "type": "array", - "items": { - "type": "string" - }, - "default": [], - "description": "List of specific tools to disable" - }, - "tools": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "string" - } - ], - "default": [ - "fs", - "git", - "interact", - "terminal", - "search", - "web", - "email", - "user" - ], - "description": "List of tools to use. Can be built-in tool names or paths to custom tool files. Default: fs,git,interact,terminal,search,web,email,user" - }, - "include": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Comma separated glob patterns or paths, eg --include=src/*.tsx,src/*.ts --include=package.json" - }, - "api_key": { - "type": "string", - "description": "Explicit API key to use" - }, - "model": { - "type": "string", - "description": "AI model to use for processing. Available models:\n\u001b[35m\u001b[1m\u001b[22m\u001b[39m\n\u001b[35m\u001b[1m OpenRouter models:\u001b[22m\u001b[39m\n\u001b[35m\u001b[1m\u001b[22m\u001b[39m\n01-ai/yi-large | paid\naetherwiing/mn-starcannon-12b | paid\nai21/jamba-1-5-large | paid\nai21/jamba-1-5-mini | paid\nai21/jamba-instruct | paid\naion-labs/aion-1.0 | paid\naion-labs/aion-1.0-mini | paid\naion-labs/aion-rp-llama-3.1-8b | paid\njondurbin/airoboros-l2-70b | paid\namazon/nova-lite-v1 | paid\namazon/nova-micro-v1 | paid\namazon/nova-pro-v1 | paid\nanthropic/claude-3-haiku | paid\nanthropic/claude-3-haiku:beta | paid\nanthropic/claude-3-opus | paid\nanthropic/claude-3-opus:beta | paid\nanthropic/claude-3-sonnet | paid\nanthropic/claude-3-sonnet:beta | paid\nanthropic/claude-3.5-haiku | paid\nanthropic/claude-3.5-haiku-20241022 | paid\nanthropic/claude-3.5-haiku-20241022:beta | paid\nanthropic/claude-3.5-haiku:beta | paid\nanthropic/claude-3.5-sonnet | paid\nanthropic/claude-3.5-sonnet-20240620 | paid\nanthropic/claude-3.5-sonnet-20240620:beta | paid\nanthropic/claude-3.5-sonnet:beta | paid\nanthropic/claude-2 | paid\nanthropic/claude-2:beta | paid\nanthropic/claude-2.0 | paid\nanthropic/claude-2.0:beta | paid\nanthropic/claude-2.1 | paid\nanthropic/claude-2.1:beta | paid\nopenrouter/auto | paid\ncohere/command | paid\ncohere/command-r | paid\ncohere/command-r-03-2024 | paid\ncohere/command-r-08-2024 | paid\ncohere/command-r-plus | paid\ncohere/command-r-plus-04-2024 | paid\ncohere/command-r-plus-08-2024 | paid\ncohere/command-r7b-12-2024 | paid\ndatabricks/dbrx-instruct | paid\ndeepseek/deepseek-chat-v2.5 | paid\ndeepseek/deepseek-chat | paid\ndeepseek/deepseek-chat:free | free\ndeepseek/deepseek-r1 | paid\ndeepseek/deepseek-r1:free | free\ndeepseek/deepseek-r1-distill-llama-70b | paid\ndeepseek/deepseek-r1-distill-llama-70b:free | free\ndeepseek/deepseek-r1-distill-llama-8b | paid\ndeepseek/deepseek-r1-distill-qwen-1.5b | paid\ndeepseek/deepseek-r1-distill-qwen-14b | paid\ndeepseek/deepseek-r1-distill-qwen-32b | paid\ncognitivecomputations/dolphin-mixtral-8x7b | paid\ncognitivecomputations/dolphin-mixtral-8x22b | paid\neva-unit-01/eva-llama-3.33-70b | paid\neva-unit-01/eva-qwen-2.5-32b | paid\neva-unit-01/eva-qwen-2.5-72b | paid\nsao10k/fimbulvetr-11b-v2 | paid\nalpindale/goliath-120b | paid\ngoogle/gemini-2.0-flash-thinking-exp-1219:free | free\ngoogle/gemini-2.0-flash-thinking-exp:free | free\ngoogle/gemini-exp-1206:free | free\ngoogle/gemini-flash-1.5 | paid\ngoogle/gemini-flash-1.5-8b | paid\ngoogle/gemini-flash-1.5-8b-exp | paid\ngoogle/gemini-2.0-flash-001 | paid\ngoogle/gemini-2.0-flash-exp:free | free\ngoogle/gemini-2.0-flash-lite-preview-02-05:free | free\ngoogle/gemini-pro | paid\ngoogle/gemini-pro-1.5 | paid\ngoogle/gemini-2.0-pro-exp-02-05:free | free\ngoogle/gemini-pro-vision | paid\ngoogle/gemma-2-27b-it | paid\ngoogle/gemma-2-9b-it | paid\ngoogle/gemma-2-9b-it:free | free\ngoogle/gemma-7b-it | paid\ngoogle/learnlm-1.5-pro-experimental:free | free\ngoogle/palm-2-chat-bison | paid\ngoogle/palm-2-chat-bison-32k | paid\ngoogle/palm-2-codechat-bison | paid\ngoogle/palm-2-codechat-bison-32k | paid\nhuggingfaceh4/zephyr-7b-beta:free | free\ninfermatic/mn-inferor-12b | paid\ninflection/inflection-3-pi | paid\ninflection/inflection-3-productivity | paid\nliquid/lfm-3b | paid\nliquid/lfm-40b | paid\nliquid/lfm-7b | paid\nallenai/llama-3.1-tulu-3-405b | paid\nalpindale/magnum-72b | paid\nanthracite-org/magnum-v2-72b | paid\nanthracite-org/magnum-v4-72b | paid\nmancer/weaver | paid\nmeta-llama/llama-2-13b-chat | paid\nmeta-llama/llama-2-70b-chat | paid\nmeta-llama/llama-3-70b-instruct | paid\nmeta-llama/llama-3-8b-instruct | paid\nmeta-llama/llama-3-8b-instruct:free | free\nmeta-llama/llama-3.1-405b | paid\nmeta-llama/llama-3.1-405b-instruct | paid\nmeta-llama/llama-3.1-70b-instruct | paid\nmeta-llama/llama-3.1-8b-instruct | paid\nmeta-llama/llama-3.2-11b-vision-instruct | paid\nmeta-llama/llama-3.2-11b-vision-instruct:free | free\nmeta-llama/llama-3.2-1b-instruct | paid\nmeta-llama/llama-3.2-3b-instruct | paid\nmeta-llama/llama-3.2-90b-vision-instruct | paid\nmeta-llama/llama-3.3-70b-instruct | paid\nmeta-llama/llama-3.3-70b-instruct:free | free\nmeta-llama/llama-guard-2-8b | paid\nmicrosoft/phi-4 | paid\nmicrosoft/phi-3-medium-128k-instruct | paid\nmicrosoft/phi-3-medium-128k-instruct:free | free\nmicrosoft/phi-3-mini-128k-instruct | paid\nmicrosoft/phi-3-mini-128k-instruct:free | free\nmicrosoft/phi-3.5-mini-128k-instruct | paid\nsophosympatheia/midnight-rose-70b | paid\nminimax/minimax-01 | paid\nmistralai/mistral-large | paid\nmistralai/mistral-large-2407 | paid\nmistralai/mistral-large-2411 | paid\nmistralai/mistral-medium | paid\nnothingiisreal/mn-celeste-12b | paid\nmistralai/mistral-small | paid\nmistralai/mistral-tiny | paid\nmistralai/codestral-2501 | paid\nmistralai/codestral-mamba | paid\nmistralai/ministral-3b | paid\nmistralai/ministral-8b | paid\nmistralai/mistral-7b-instruct | paid\nmistralai/mistral-7b-instruct:free | free\nmistralai/mistral-7b-instruct-v0.1 | paid\nmistralai/mistral-7b-instruct-v0.3 | paid\nmistralai/mistral-nemo | paid\nmistralai/mistral-small-24b-instruct-2501 | paid\nmistralai/mixtral-8x22b-instruct | paid\nmistralai/mixtral-8x7b | paid\nmistralai/mixtral-8x7b-instruct | paid\nmistralai/pixtral-12b | paid\nmistralai/pixtral-large-2411 | paid\ngryphe/mythomax-l2-13b | paid\ngryphe/mythomax-l2-13b:free | free\nneversleep/llama-3-lumimaid-70b | paid\nneversleep/llama-3-lumimaid-8b | paid\nneversleep/llama-3-lumimaid-8b:extended | paid\nneversleep/llama-3.1-lumimaid-70b | paid\nneversleep/llama-3.1-lumimaid-8b | paid\nneversleep/noromaid-20b | paid\nnousresearch/nous-hermes-llama2-13b | paid\nnousresearch/nous-hermes-2-mixtral-8x7b-dpo | paid\nnousresearch/hermes-3-llama-3.1-405b | paid\nnousresearch/hermes-3-llama-3.1-70b | paid\nnousresearch/hermes-2-pro-llama-3-8b | paid\nnvidia/llama-3.1-nemotron-70b-instruct | paid\nnvidia/llama-3.1-nemotron-70b-instruct:free | free\nopenai/chatgpt-4o-latest | paid\nopenai/gpt-3.5-turbo | paid\nopenai/gpt-3.5-turbo-0613 | paid\nopenai/gpt-3.5-turbo-16k | paid\nopenai/gpt-3.5-turbo-0125 | paid\nopenai/gpt-3.5-turbo-1106 | paid\nopenai/gpt-3.5-turbo-instruct | paid\nopenai/gpt-4 | paid\nopenai/gpt-4-0314 | paid\nopenai/gpt-4-32k | paid\nopenai/gpt-4-32k-0314 | paid\nopenai/gpt-4-turbo | paid\nopenai/gpt-4-1106-preview | paid\nopenai/gpt-4-turbo-preview | paid\nopenai/gpt-4o | paid\nopenai/gpt-4o-2024-05-13 | paid\nopenai/gpt-4o-2024-08-06 | paid\nopenai/gpt-4o-2024-11-20 | paid\nopenai/gpt-4o:extended | paid\nopenai/gpt-4o-mini | paid\nopenai/gpt-4o-mini-2024-07-18 | paid\nopenai/o1 | paid\nopenai/o1-mini | paid\nopenai/o1-mini-2024-09-12 | paid\nopenai/o1-preview | paid\nopenai/o1-preview-2024-09-12 | paid\nopenai/o3-mini | paid\nopenchat/openchat-7b | paid\nopenchat/openchat-7b:free | free\nteknium/openhermes-2.5-mistral-7b | paid\nperplexity/llama-3.1-sonar-huge-128k-online | paid\nperplexity/llama-3.1-sonar-large-128k-chat | paid\nperplexity/llama-3.1-sonar-large-128k-online | paid\nperplexity/llama-3.1-sonar-small-128k-chat | paid\nperplexity/llama-3.1-sonar-small-128k-online | paid\nperplexity/sonar | paid\nperplexity/sonar-reasoning | paid\npygmalionai/mythalion-13b | paid\nqwen/qwen-2-72b-instruct | paid\nqwen/qwen-2-7b-instruct | paid\nqwen/qwen-2-7b-instruct:free | free\nqwen/qvq-72b-preview | paid\nqwen/qwen-vl-plus:free | free\nqwen/qwen-max | paid\nqwen/qwen-plus | paid\nqwen/qwen-turbo | paid\nqwen/qwen2.5-vl-72b-instruct:free | free\nqwen/qwq-32b-preview | paid\nqwen/qwen-2-vl-72b-instruct | paid\nqwen/qwen-2-vl-7b-instruct | paid\nqwen/qwen-2.5-72b-instruct | paid\nqwen/qwen-2.5-7b-instruct | paid\nqwen/qwen-2.5-coder-32b-instruct | paid\nundi95/remm-slerp-l2-13b | paid\nthedrummer/rocinante-12b | paid\nsophosympatheia/rogue-rose-103b-v0.2:free | free\nsao10k/l3-lunaris-8b | paid\nsao10k/l3-euryale-70b | paid\nsao10k/l3.1-70b-hanami-x1 | paid\nsao10k/l3.1-euryale-70b | paid\nsao10k/l3.3-euryale-70b | paid\nraifle/sorcererlm-8x22b | paid\nundi95/toppy-m-7b | paid\nundi95/toppy-m-7b:free | free\nthedrummer/unslopnemo-12b | paid\nmicrosoft/wizardlm-2-7b | paid\nmicrosoft/wizardlm-2-8x22b | paid\nx-ai/grok-2-1212 | paid\nx-ai/grok-2-vision-1212 | paid\nx-ai/grok-beta | paid\nx-ai/grok-vision-beta | paid\nxwin-lm/xwin-lm-70b | paid\n\u001b[35m\u001b[1m\u001b[22m\u001b[39m\n\u001b[35m\u001b[1m OpenAI models:\u001b[22m\u001b[39m\n\u001b[35m\u001b[1m\u001b[22m\u001b[39m\nbabbage-002\nchatgpt-4o-latest\ndall-e-2\ndall-e-3\ndavinci-002\ngpt-3.5-turbo\ngpt-3.5-turbo-0125\ngpt-3.5-turbo-1106\ngpt-3.5-turbo-16k\ngpt-3.5-turbo-instruct\ngpt-3.5-turbo-instruct-0914\ngpt-4\ngpt-4-0125-preview\ngpt-4-0613\ngpt-4-1106-preview\ngpt-4-turbo\ngpt-4-turbo-2024-04-09\ngpt-4-turbo-preview\ngpt-4o\ngpt-4o-2024-05-13\ngpt-4o-2024-08-06\ngpt-4o-2024-11-20\ngpt-4o-audio-preview\ngpt-4o-audio-preview-2024-10-01\ngpt-4o-audio-preview-2024-12-17\ngpt-4o-mini\ngpt-4o-mini-2024-07-18\ngpt-4o-mini-audio-preview\ngpt-4o-mini-audio-preview-2024-12-17\ngpt-4o-mini-realtime-preview\ngpt-4o-mini-realtime-preview-2024-12-17\ngpt-4o-realtime-preview\ngpt-4o-realtime-preview-2024-10-01\ngpt-4o-realtime-preview-2024-12-17\no1-mini\no1-mini-2024-09-12\no1-preview\no1-preview-2024-09-12\nomni-moderation-2024-09-26\nomni-moderation-latest\ntext-embedding-3-large\ntext-embedding-3-small\ntext-embedding-ada-002\ntts-1\ntts-1-1106\ntts-1-hd\ntts-1-hd-1106\nwhisper-1\n-----\n\n\u001b[35m\u001b[1m\u001b[22m\u001b[39m\n\u001b[35m\u001b[1m Deepseek models:\u001b[22m\u001b[39m\n\u001b[35m\u001b[1m\u001b[22m\u001b[39m\ndeepseek-chat\ndeepseek-reasoner\n-----\n" - }, - "router": { - "type": "string", - "default": "openrouter", - "description": "Router to use: openai, openrouter or deepseek" - }, - "mode": { - "type": "string", - "enum": [ - "completion", - "tools", - "assistant", - "custom" - ], - "default": "tools", - "description": "Chat completion mode:\n\t completion, tools, assistant.\n \u001b[32m\u001b[1mcompletion\u001b[22m\u001b[39m: no support for tools, please use --dst parameter to save the output.\n \u001b[32m\u001b[1mtools\u001b[22m\u001b[39m: allows for tools to be used, eg 'save to ./output.md'. Not all models support this mode.\n \u001b[32m\u001b[1massistant\u001b[22m\u001b[39m: : allows documents (PDF, DOCX, ...) to be added but dont support tools. Use --dst to save the output. Supported files :\n \u001b[32m\u001b[1mcustom\u001b[22m\u001b[39m: custom mode\n " - }, - "logLevel": { - "type": "number", - "default": 2, - "description": "Logging level for the application" - }, - "profile": { - "type": "string", - "description": "Path to profile for variables. Supports environment variables." - }, - "baseURL": { - "type": "string", - "description": "Base URL for the API, set via --router or directly" - }, - "config": { - "type": "string", - "description": "Path to JSON configuration file (API keys). Supports environment variables." - }, - "dump": { - "type": "string", - "description": "Create a script" - }, - "preferences": { - "type": "string", - "default": "./.kbot/preferences.md", - "description": "Path to preferences file, eg: location, your email address, gender, etc. Supports environment variables." - }, - "logs": { - "type": "string", - "default": "./.kbot", - "description": "Logging directory" - }, - "env": { - "type": "string", - "default": "default", - "description": "Environment (in profile)" - }, - "variables": { - "type": "object", - "additionalProperties": { - "type": "string" - }, - "default": {} - }, - "filters": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string", - "enum": [ - "JSON", - "JSONUnescape", - "JSONPretty", - "AlphaSort", - "code", - "JSONParse", - "trim" - ] - } - }, - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "array" - } - ], - "default": "", - "description": "List of filters to apply to the output.\n Used only in completion mode and a given output file specified with --dst. \n It unwraps by default any code or data in Markdown. \n Choices:\n\tJSON,JSONUnescape,JSONPretty,AlphaSort,code,JSONParse,trim\n" - }, - "dry": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "string" - } - ], - "default": false, - "description": "Dry run - only write out parameters without making API calls" - } - }, - "additionalProperties": true, - "description": "IKBotOptions" - } - }, - "$schema": "http://json-schema.org/draft-07/schema#" - } -] \ No newline at end of file diff --git a/packages/ai-tools/schema_ui.json b/packages/ai-tools/schema_ui.json deleted file mode 100644 index cd1fdfef..00000000 --- a/packages/ai-tools/schema_ui.json +++ /dev/null @@ -1,129 +0,0 @@ -{ - "ui:submitButtonOptions": { - "props": { - "disabled": false, - "className": "btn btn-info" - }, - "norender": false, - "submitText": "Submit" - }, - "path": { - "ui:description": "Target directory", - "ui:title": "Path", - "ui:placeholder": ".", - "ui:widget": "file" - }, - "prompt": { - "ui:description": "The prompt. Supports file paths and environment variables.", - "ui:title": "Prompt", - "ui:placeholder": "./prompt.md" - }, - "output": { - "ui:description": "Optional output path for modified files (Tool mode only)", - "ui:title": "Output" - }, - "dst": { - "ui:description": "Optional destination path for the result, will substitute ${MODEL_NAME} and ${ROUTER} in the path. Optional, used for \"completion\" mode", - "ui:title": "Dst" - }, - "each": { - "ui:description": "Iterate over items, supported: GLOB | Path to JSON File | array of strings (comma separated). To test different models, use --each=\"gpt-3.5-turbo,gpt-4o\", the actual string will exposed as variable `ITEM`, eg: --dst=\"${ITEM}-output.md\"", - "ui:title": "Each" - }, - "disable": { - "ui:description": "Disable tools categories, eg: --disable=fs,git,interact,terminal,search,web,email,user", - "ui:title": "Disable", - "ui:placeholder": [] - }, - "disableTools": { - "ui:description": "List of specific tools to disable", - "ui:title": "Disabletools", - "ui:placeholder": [] - }, - "tools": { - "ui:description": "List of tools to use. Can be built-in tool names or paths to custom tool files. Default: fs,git,interact,terminal,search,web,email,user", - "ui:title": "Tools", - "ui:placeholder": [ - "fs", - "git", - "interact", - "terminal", - "search", - "web", - "email", - "user" - ] - }, - "include": { - "ui:description": "Comma separated glob patterns or paths, eg --include=src/*.tsx,src/*.ts --include=package.json", - "ui:title": "Include" - }, - "api_key": { - "ui:description": "Explicit API key to use", - "ui:title": "Api_key" - }, - "model": { - "ui:description": "AI model to use for processing. Available models:\n\u001b[35m\u001b[1m\u001b[22m\u001b[39m\n\u001b[35m\u001b[1m OpenRouter models:\u001b[22m\u001b[39m\n\u001b[35m\u001b[1m\u001b[22m\u001b[39m\n01-ai/yi-large | paid\naetherwiing/mn-starcannon-12b | paid\nai21/jamba-1-5-large | paid\nai21/jamba-1-5-mini | paid\nai21/jamba-instruct | paid\naion-labs/aion-1.0 | paid\naion-labs/aion-1.0-mini | paid\naion-labs/aion-rp-llama-3.1-8b | paid\njondurbin/airoboros-l2-70b | paid\namazon/nova-lite-v1 | paid\namazon/nova-micro-v1 | paid\namazon/nova-pro-v1 | paid\nanthropic/claude-3-haiku | paid\nanthropic/claude-3-haiku:beta | paid\nanthropic/claude-3-opus | paid\nanthropic/claude-3-opus:beta | paid\nanthropic/claude-3-sonnet | paid\nanthropic/claude-3-sonnet:beta | paid\nanthropic/claude-3.5-haiku | paid\nanthropic/claude-3.5-haiku-20241022 | paid\nanthropic/claude-3.5-haiku-20241022:beta | paid\nanthropic/claude-3.5-haiku:beta | paid\nanthropic/claude-3.5-sonnet | paid\nanthropic/claude-3.5-sonnet-20240620 | paid\nanthropic/claude-3.5-sonnet-20240620:beta | paid\nanthropic/claude-3.5-sonnet:beta | paid\nanthropic/claude-2 | paid\nanthropic/claude-2:beta | paid\nanthropic/claude-2.0 | paid\nanthropic/claude-2.0:beta | paid\nanthropic/claude-2.1 | paid\nanthropic/claude-2.1:beta | paid\nopenrouter/auto | paid\ncohere/command | paid\ncohere/command-r | paid\ncohere/command-r-03-2024 | paid\ncohere/command-r-08-2024 | paid\ncohere/command-r-plus | paid\ncohere/command-r-plus-04-2024 | paid\ncohere/command-r-plus-08-2024 | paid\ncohere/command-r7b-12-2024 | paid\ndatabricks/dbrx-instruct | paid\ndeepseek/deepseek-chat-v2.5 | paid\ndeepseek/deepseek-chat | paid\ndeepseek/deepseek-chat:free | free\ndeepseek/deepseek-r1 | paid\ndeepseek/deepseek-r1:free | free\ndeepseek/deepseek-r1-distill-llama-70b | paid\ndeepseek/deepseek-r1-distill-llama-70b:free | free\ndeepseek/deepseek-r1-distill-llama-8b | paid\ndeepseek/deepseek-r1-distill-qwen-1.5b | paid\ndeepseek/deepseek-r1-distill-qwen-14b | paid\ndeepseek/deepseek-r1-distill-qwen-32b | paid\ncognitivecomputations/dolphin-mixtral-8x7b | paid\ncognitivecomputations/dolphin-mixtral-8x22b | paid\neva-unit-01/eva-llama-3.33-70b | paid\neva-unit-01/eva-qwen-2.5-32b | paid\neva-unit-01/eva-qwen-2.5-72b | paid\nsao10k/fimbulvetr-11b-v2 | paid\nalpindale/goliath-120b | paid\ngoogle/gemini-2.0-flash-thinking-exp-1219:free | free\ngoogle/gemini-2.0-flash-thinking-exp:free | free\ngoogle/gemini-exp-1206:free | free\ngoogle/gemini-flash-1.5 | paid\ngoogle/gemini-flash-1.5-8b | paid\ngoogle/gemini-flash-1.5-8b-exp | paid\ngoogle/gemini-2.0-flash-001 | paid\ngoogle/gemini-2.0-flash-exp:free | free\ngoogle/gemini-2.0-flash-lite-preview-02-05:free | free\ngoogle/gemini-pro | paid\ngoogle/gemini-pro-1.5 | paid\ngoogle/gemini-2.0-pro-exp-02-05:free | free\ngoogle/gemini-pro-vision | paid\ngoogle/gemma-2-27b-it | paid\ngoogle/gemma-2-9b-it | paid\ngoogle/gemma-2-9b-it:free | free\ngoogle/gemma-7b-it | paid\ngoogle/learnlm-1.5-pro-experimental:free | free\ngoogle/palm-2-chat-bison | paid\ngoogle/palm-2-chat-bison-32k | paid\ngoogle/palm-2-codechat-bison | paid\ngoogle/palm-2-codechat-bison-32k | paid\nhuggingfaceh4/zephyr-7b-beta:free | free\ninfermatic/mn-inferor-12b | paid\ninflection/inflection-3-pi | paid\ninflection/inflection-3-productivity | paid\nliquid/lfm-3b | paid\nliquid/lfm-40b | paid\nliquid/lfm-7b | paid\nallenai/llama-3.1-tulu-3-405b | paid\nalpindale/magnum-72b | paid\nanthracite-org/magnum-v2-72b | paid\nanthracite-org/magnum-v4-72b | paid\nmancer/weaver | paid\nmeta-llama/llama-2-13b-chat | paid\nmeta-llama/llama-2-70b-chat | paid\nmeta-llama/llama-3-70b-instruct | paid\nmeta-llama/llama-3-8b-instruct | paid\nmeta-llama/llama-3-8b-instruct:free | free\nmeta-llama/llama-3.1-405b | paid\nmeta-llama/llama-3.1-405b-instruct | paid\nmeta-llama/llama-3.1-70b-instruct | paid\nmeta-llama/llama-3.1-8b-instruct | paid\nmeta-llama/llama-3.2-11b-vision-instruct | paid\nmeta-llama/llama-3.2-11b-vision-instruct:free | free\nmeta-llama/llama-3.2-1b-instruct | paid\nmeta-llama/llama-3.2-3b-instruct | paid\nmeta-llama/llama-3.2-90b-vision-instruct | paid\nmeta-llama/llama-3.3-70b-instruct | paid\nmeta-llama/llama-3.3-70b-instruct:free | free\nmeta-llama/llama-guard-2-8b | paid\nmicrosoft/phi-4 | paid\nmicrosoft/phi-3-medium-128k-instruct | paid\nmicrosoft/phi-3-medium-128k-instruct:free | free\nmicrosoft/phi-3-mini-128k-instruct | paid\nmicrosoft/phi-3-mini-128k-instruct:free | free\nmicrosoft/phi-3.5-mini-128k-instruct | paid\nsophosympatheia/midnight-rose-70b | paid\nminimax/minimax-01 | paid\nmistralai/mistral-large | paid\nmistralai/mistral-large-2407 | paid\nmistralai/mistral-large-2411 | paid\nmistralai/mistral-medium | paid\nnothingiisreal/mn-celeste-12b | paid\nmistralai/mistral-small | paid\nmistralai/mistral-tiny | paid\nmistralai/codestral-2501 | paid\nmistralai/codestral-mamba | paid\nmistralai/ministral-3b | paid\nmistralai/ministral-8b | paid\nmistralai/mistral-7b-instruct | paid\nmistralai/mistral-7b-instruct:free | free\nmistralai/mistral-7b-instruct-v0.1 | paid\nmistralai/mistral-7b-instruct-v0.3 | paid\nmistralai/mistral-nemo | paid\nmistralai/mistral-small-24b-instruct-2501 | paid\nmistralai/mixtral-8x22b-instruct | paid\nmistralai/mixtral-8x7b | paid\nmistralai/mixtral-8x7b-instruct | paid\nmistralai/pixtral-12b | paid\nmistralai/pixtral-large-2411 | paid\ngryphe/mythomax-l2-13b | paid\ngryphe/mythomax-l2-13b:free | free\nneversleep/llama-3-lumimaid-70b | paid\nneversleep/llama-3-lumimaid-8b | paid\nneversleep/llama-3-lumimaid-8b:extended | paid\nneversleep/llama-3.1-lumimaid-70b | paid\nneversleep/llama-3.1-lumimaid-8b | paid\nneversleep/noromaid-20b | paid\nnousresearch/nous-hermes-llama2-13b | paid\nnousresearch/nous-hermes-2-mixtral-8x7b-dpo | paid\nnousresearch/hermes-3-llama-3.1-405b | paid\nnousresearch/hermes-3-llama-3.1-70b | paid\nnousresearch/hermes-2-pro-llama-3-8b | paid\nnvidia/llama-3.1-nemotron-70b-instruct | paid\nnvidia/llama-3.1-nemotron-70b-instruct:free | free\nopenai/chatgpt-4o-latest | paid\nopenai/gpt-3.5-turbo | paid\nopenai/gpt-3.5-turbo-0613 | paid\nopenai/gpt-3.5-turbo-16k | paid\nopenai/gpt-3.5-turbo-0125 | paid\nopenai/gpt-3.5-turbo-1106 | paid\nopenai/gpt-3.5-turbo-instruct | paid\nopenai/gpt-4 | paid\nopenai/gpt-4-0314 | paid\nopenai/gpt-4-32k | paid\nopenai/gpt-4-32k-0314 | paid\nopenai/gpt-4-turbo | paid\nopenai/gpt-4-1106-preview | paid\nopenai/gpt-4-turbo-preview | paid\nopenai/gpt-4o | paid\nopenai/gpt-4o-2024-05-13 | paid\nopenai/gpt-4o-2024-08-06 | paid\nopenai/gpt-4o-2024-11-20 | paid\nopenai/gpt-4o:extended | paid\nopenai/gpt-4o-mini | paid\nopenai/gpt-4o-mini-2024-07-18 | paid\nopenai/o1 | paid\nopenai/o1-mini | paid\nopenai/o1-mini-2024-09-12 | paid\nopenai/o1-preview | paid\nopenai/o1-preview-2024-09-12 | paid\nopenai/o3-mini | paid\nopenchat/openchat-7b | paid\nopenchat/openchat-7b:free | free\nteknium/openhermes-2.5-mistral-7b | paid\nperplexity/llama-3.1-sonar-huge-128k-online | paid\nperplexity/llama-3.1-sonar-large-128k-chat | paid\nperplexity/llama-3.1-sonar-large-128k-online | paid\nperplexity/llama-3.1-sonar-small-128k-chat | paid\nperplexity/llama-3.1-sonar-small-128k-online | paid\nperplexity/sonar | paid\nperplexity/sonar-reasoning | paid\npygmalionai/mythalion-13b | paid\nqwen/qwen-2-72b-instruct | paid\nqwen/qwen-2-7b-instruct | paid\nqwen/qwen-2-7b-instruct:free | free\nqwen/qvq-72b-preview | paid\nqwen/qwen-vl-plus:free | free\nqwen/qwen-max | paid\nqwen/qwen-plus | paid\nqwen/qwen-turbo | paid\nqwen/qwen2.5-vl-72b-instruct:free | free\nqwen/qwq-32b-preview | paid\nqwen/qwen-2-vl-72b-instruct | paid\nqwen/qwen-2-vl-7b-instruct | paid\nqwen/qwen-2.5-72b-instruct | paid\nqwen/qwen-2.5-7b-instruct | paid\nqwen/qwen-2.5-coder-32b-instruct | paid\nundi95/remm-slerp-l2-13b | paid\nthedrummer/rocinante-12b | paid\nsophosympatheia/rogue-rose-103b-v0.2:free | free\nsao10k/l3-lunaris-8b | paid\nsao10k/l3-euryale-70b | paid\nsao10k/l3.1-70b-hanami-x1 | paid\nsao10k/l3.1-euryale-70b | paid\nsao10k/l3.3-euryale-70b | paid\nraifle/sorcererlm-8x22b | paid\nundi95/toppy-m-7b | paid\nundi95/toppy-m-7b:free | free\nthedrummer/unslopnemo-12b | paid\nmicrosoft/wizardlm-2-7b | paid\nmicrosoft/wizardlm-2-8x22b | paid\nx-ai/grok-2-1212 | paid\nx-ai/grok-2-vision-1212 | paid\nx-ai/grok-beta | paid\nx-ai/grok-vision-beta | paid\nxwin-lm/xwin-lm-70b | paid\n\u001b[35m\u001b[1m\u001b[22m\u001b[39m\n\u001b[35m\u001b[1m OpenAI models:\u001b[22m\u001b[39m\n\u001b[35m\u001b[1m\u001b[22m\u001b[39m\nbabbage-002\nchatgpt-4o-latest\ndall-e-2\ndall-e-3\ndavinci-002\ngpt-3.5-turbo\ngpt-3.5-turbo-0125\ngpt-3.5-turbo-1106\ngpt-3.5-turbo-16k\ngpt-3.5-turbo-instruct\ngpt-3.5-turbo-instruct-0914\ngpt-4\ngpt-4-0125-preview\ngpt-4-0613\ngpt-4-1106-preview\ngpt-4-turbo\ngpt-4-turbo-2024-04-09\ngpt-4-turbo-preview\ngpt-4o\ngpt-4o-2024-05-13\ngpt-4o-2024-08-06\ngpt-4o-2024-11-20\ngpt-4o-audio-preview\ngpt-4o-audio-preview-2024-10-01\ngpt-4o-audio-preview-2024-12-17\ngpt-4o-mini\ngpt-4o-mini-2024-07-18\ngpt-4o-mini-audio-preview\ngpt-4o-mini-audio-preview-2024-12-17\ngpt-4o-mini-realtime-preview\ngpt-4o-mini-realtime-preview-2024-12-17\ngpt-4o-realtime-preview\ngpt-4o-realtime-preview-2024-10-01\ngpt-4o-realtime-preview-2024-12-17\no1-mini\no1-mini-2024-09-12\no1-preview\no1-preview-2024-09-12\nomni-moderation-2024-09-26\nomni-moderation-latest\ntext-embedding-3-large\ntext-embedding-3-small\ntext-embedding-ada-002\ntts-1\ntts-1-1106\ntts-1-hd\ntts-1-hd-1106\nwhisper-1\n-----\n\n\u001b[35m\u001b[1m\u001b[22m\u001b[39m\n\u001b[35m\u001b[1m Deepseek models:\u001b[22m\u001b[39m\n\u001b[35m\u001b[1m\u001b[22m\u001b[39m\ndeepseek-chat\ndeepseek-reasoner\n-----\n", - "ui:title": "Model" - }, - "router": { - "ui:description": "Router to use: openai, openrouter or deepseek", - "ui:title": "Router", - "ui:placeholder": "openrouter" - }, - "mode": { - "ui:description": "Chat completion mode:\n\t completion, tools, assistant.\n \u001b[32m\u001b[1mcompletion\u001b[22m\u001b[39m: no support for tools, please use --dst parameter to save the output.\n \u001b[32m\u001b[1mtools\u001b[22m\u001b[39m: allows for tools to be used, eg 'save to ./output.md'. Not all models support this mode.\n \u001b[32m\u001b[1massistant\u001b[22m\u001b[39m: : allows documents (PDF, DOCX, ...) to be added but dont support tools. Use --dst to save the output. Supported files :\n \u001b[32m\u001b[1mcustom\u001b[22m\u001b[39m: custom mode\n ", - "ui:title": "Mode", - "ui:placeholder": "tools" - }, - "logLevel": { - "ui:description": "Logging level for the application", - "ui:title": "Loglevel", - "ui:placeholder": 2 - }, - "profile": { - "ui:description": "Path to profile for variables. Supports environment variables.", - "ui:title": "Profile" - }, - "baseURL": { - "ui:description": "Base URL for the API, set via --router or directly", - "ui:title": "Baseurl" - }, - "config": { - "ui:description": "Path to JSON configuration file (API keys). Supports environment variables.", - "ui:title": "Config" - }, - "dump": { - "ui:description": "Create a script", - "ui:title": "Dump" - }, - "preferences": { - "ui:description": "Path to preferences file, eg: location, your email address, gender, etc. Supports environment variables.", - "ui:title": "Preferences", - "ui:placeholder": "./.kbot/preferences.md" - }, - "logs": { - "ui:description": "Logging directory", - "ui:title": "Logs", - "ui:placeholder": "./.kbot" - }, - "env": { - "ui:description": "Environment (in profile)", - "ui:title": "Env", - "ui:placeholder": "default" - }, - "variables": { - "ui:title": "Variables", - "ui:placeholder": {} - }, - "filters": { - "ui:description": "List of filters to apply to the output.\n Used only in completion mode and a given output file specified with --dst. \n It unwraps by default any code or data in Markdown. \n Choices:\n\tJSON,JSONUnescape,JSONPretty,AlphaSort,code,JSONParse,trim\n", - "ui:title": "Filters", - "ui:placeholder": [] - }, - "dry": { - "ui:description": "Dry run - only write out parameters without making API calls", - "ui:title": "Dry", - "ui:placeholder": false - } -} \ No newline at end of file diff --git a/packages/ai-tools/src/types_kbot.ts b/packages/ai-tools/src/types_kbot.ts index 56294493..909dba60 100644 --- a/packages/ai-tools/src/types_kbot.ts +++ b/packages/ai-tools/src/types_kbot.ts @@ -27,10 +27,14 @@ export interface IKBotOptions { aetherwiing/mn-starcannon-12b | paid ai21/jamba-1-5-large | paid ai21/jamba-1-5-mini | paid + ai21/jamba-1.6-large | paid ai21/jamba-instruct | paid + ai21/jamba-1.6-mini | paid aion-labs/aion-1.0 | paid aion-labs/aion-1.0-mini | paid aion-labs/aion-rp-llama-3.1-8b | paid + jondurbin/airoboros-l2-70b | paid + allenai/olmo-2-0325-32b-instruct | paid amazon/nova-lite-v1 | paid amazon/nova-micro-v1 | paid amazon/nova-pro-v1 | paid @@ -48,6 +52,9 @@ export interface IKBotOptions { anthropic/claude-3.5-sonnet-20240620 | paid anthropic/claude-3.5-sonnet-20240620:beta | paid anthropic/claude-3.5-sonnet:beta | paid + anthropic/claude-3.7-sonnet | paid + anthropic/claude-3.7-sonnet:beta | paid + anthropic/claude-3.7-sonnet:thinking | paid anthropic/claude-2 | paid anthropic/claude-2:beta | paid anthropic/claude-2.0 | paid @@ -56,6 +63,7 @@ export interface IKBotOptions { anthropic/claude-2.1:beta | paid openrouter/auto | paid cohere/command | paid + cohere/command-a | paid cohere/command-r | paid cohere/command-r-03-2024 | paid cohere/command-r-08-2024 | paid @@ -63,18 +71,21 @@ export interface IKBotOptions { cohere/command-r-plus-04-2024 | paid cohere/command-r-plus-08-2024 | paid cohere/command-r7b-12-2024 | paid - databricks/dbrx-instruct | paid - deepseek/deepseek-chat-v2.5 | paid + deepseek/deepseek-r1-zero:free | free deepseek/deepseek-chat | paid deepseek/deepseek-chat:free | free deepseek/deepseek-r1 | paid deepseek/deepseek-r1:free | free deepseek/deepseek-r1-distill-llama-70b | paid deepseek/deepseek-r1-distill-llama-70b:free | free + deepseek/deepseek-r1-distill-llama-8b | paid deepseek/deepseek-r1-distill-qwen-1.5b | paid deepseek/deepseek-r1-distill-qwen-14b | paid + deepseek/deepseek-r1-distill-qwen-14b:free | free deepseek/deepseek-r1-distill-qwen-32b | paid + deepseek/deepseek-r1-distill-qwen-32b:free | free cognitivecomputations/dolphin-mixtral-8x7b | paid + cognitivecomputations/dolphin-mixtral-8x22b | paid cognitivecomputations/dolphin3.0-mistral-24b:free | free cognitivecomputations/dolphin3.0-r1-mistral-24b:free | free eva-unit-01/eva-llama-3.33-70b | paid @@ -82,6 +93,7 @@ export interface IKBotOptions { eva-unit-01/eva-qwen-2.5-72b | paid sao10k/fimbulvetr-11b-v2 | paid alpindale/goliath-120b | paid + google/gemini-2.0-flash-lite-001 | paid google/gemini-2.0-flash-thinking-exp-1219:free | free google/gemini-2.0-flash-thinking-exp:free | free google/gemini-exp-1206:free | free @@ -98,6 +110,11 @@ export interface IKBotOptions { google/gemma-2-27b-it | paid google/gemma-2-9b-it | paid google/gemma-2-9b-it:free | free + google/gemma-3-12b-it:free | free + google/gemma-3-1b-it:free | free + google/gemma-3-27b-it | paid + google/gemma-3-27b-it:free | free + google/gemma-3-4b-it:free | free google/gemma-7b-it | paid google/learnlm-1.5-pro-experimental:free | free google/palm-2-chat-bison | paid @@ -108,6 +125,7 @@ export interface IKBotOptions { infermatic/mn-inferor-12b | paid inflection/inflection-3-pi | paid inflection/inflection-3-productivity | paid + latitudegames/wayfarer-large-70b-llama-3.3 | paid liquid/lfm-3b | paid liquid/lfm-40b | paid liquid/lfm-7b | paid @@ -126,20 +144,25 @@ export interface IKBotOptions { meta-llama/llama-3.1-405b-instruct | paid meta-llama/llama-3.1-70b-instruct | paid meta-llama/llama-3.1-8b-instruct | paid + meta-llama/llama-3.1-8b-instruct:free | free meta-llama/llama-3.2-11b-vision-instruct | paid meta-llama/llama-3.2-11b-vision-instruct:free | free meta-llama/llama-3.2-1b-instruct | paid + meta-llama/llama-3.2-1b-instruct:free | free meta-llama/llama-3.2-3b-instruct | paid + meta-llama/llama-3.2-3b-instruct:free | free meta-llama/llama-3.2-90b-vision-instruct | paid meta-llama/llama-3.3-70b-instruct | paid meta-llama/llama-3.3-70b-instruct:free | free meta-llama/llama-guard-2-8b | paid microsoft/phi-4 | paid + microsoft/phi-4-multimodal-instruct | paid microsoft/phi-3-medium-128k-instruct | paid microsoft/phi-3-medium-128k-instruct:free | free microsoft/phi-3-mini-128k-instruct | paid microsoft/phi-3-mini-128k-instruct:free | free microsoft/phi-3.5-mini-128k-instruct | paid + sophosympatheia/midnight-rose-70b | paid minimax/minimax-01 | paid mistralai/mistral-large | paid mistralai/mistral-large-2407 | paid @@ -155,17 +178,20 @@ export interface IKBotOptions { mistralai/mistral-7b-instruct | paid mistralai/mistral-7b-instruct:free | free mistralai/mistral-7b-instruct-v0.1 | paid + mistralai/mistral-7b-instruct-v0.2 | paid mistralai/mistral-7b-instruct-v0.3 | paid mistralai/mistral-nemo | paid mistralai/mistral-nemo:free | free mistralai/mistral-small-24b-instruct-2501 | paid mistralai/mistral-small-24b-instruct-2501:free | free + mistralai/mistral-small-3.1-24b-instruct | paid mistralai/mixtral-8x22b-instruct | paid mistralai/mixtral-8x7b | paid mistralai/mixtral-8x7b-instruct | paid mistralai/pixtral-12b | paid mistralai/pixtral-large-2411 | paid mistralai/mistral-saba | paid + moonshotai/moonlight-16b-a3b-instruct:free | free gryphe/mythomax-l2-13b | paid gryphe/mythomax-l2-13b:free | free neversleep/llama-3-lumimaid-70b | paid @@ -174,6 +200,7 @@ export interface IKBotOptions { neversleep/llama-3.1-lumimaid-70b | paid neversleep/llama-3.1-lumimaid-8b | paid neversleep/noromaid-20b | paid + nousresearch/deephermes-3-llama-3-8b-preview:free | free nousresearch/nous-hermes-llama2-13b | paid nousresearch/nous-hermes-2-mixtral-8x7b-dpo | paid nousresearch/hermes-3-llama-3.1-405b | paid @@ -181,6 +208,8 @@ export interface IKBotOptions { nousresearch/hermes-2-pro-llama-3-8b | paid nvidia/llama-3.1-nemotron-70b-instruct | paid nvidia/llama-3.1-nemotron-70b-instruct:free | free + open-r1/olympiccoder-32b:free | free + open-r1/olympiccoder-7b:free | free openai/chatgpt-4o-latest | paid openai/gpt-3.5-turbo | paid openai/gpt-3.5-turbo-0613 | paid @@ -195,13 +224,16 @@ export interface IKBotOptions { openai/gpt-4-turbo | paid openai/gpt-4-1106-preview | paid openai/gpt-4-turbo-preview | paid + openai/gpt-4.5-preview | paid openai/gpt-4o | paid openai/gpt-4o-2024-05-13 | paid openai/gpt-4o-2024-08-06 | paid openai/gpt-4o-2024-11-20 | paid openai/gpt-4o:extended | paid + openai/gpt-4o-search-preview | paid openai/gpt-4o-mini | paid openai/gpt-4o-mini-2024-07-18 | paid + openai/gpt-4o-mini-search-preview | paid openai/o1 | paid openai/o1-mini | paid openai/o1-mini-2024-09-12 | paid @@ -211,27 +243,41 @@ export interface IKBotOptions { openai/o3-mini-high | paid openchat/openchat-7b | paid openchat/openchat-7b:free | free - perplexity/llama-3.1-sonar-huge-128k-online | paid + teknium/openhermes-2.5-mistral-7b | paid perplexity/llama-3.1-sonar-large-128k-chat | paid perplexity/llama-3.1-sonar-large-128k-online | paid perplexity/llama-3.1-sonar-small-128k-chat | paid perplexity/llama-3.1-sonar-small-128k-online | paid + perplexity/r1-1776 | paid perplexity/sonar | paid + perplexity/sonar-deep-research | paid + perplexity/sonar-pro | paid perplexity/sonar-reasoning | paid + perplexity/sonar-reasoning-pro | paid pygmalionai/mythalion-13b | paid qwen/qwen-2-72b-instruct | paid - qwen/qvq-72b-preview | paid - qwen/qwen-vl-plus:free | free + qwen/qwen-2-7b-instruct | paid + qwen/qwen-2-7b-instruct:free | free + qwen/qwen-vl-max | paid + qwen/qwen-vl-plus | paid qwen/qwen-max | paid qwen/qwen-plus | paid qwen/qwen-turbo | paid + qwen/qwen2.5-32b-instruct | paid + qwen/qwen2.5-vl-72b-instruct | paid qwen/qwen2.5-vl-72b-instruct:free | free + qwen/qwen-2.5-vl-72b-instruct | paid + qwen/qwen-2.5-vl-7b-instruct | paid + qwen/qwq-32b | paid + qwen/qwq-32b:free | free qwen/qwq-32b-preview | paid - qwen/qwen-2-vl-72b-instruct | paid - qwen/qwen-2-vl-7b-instruct | paid + qwen/qwq-32b-preview:free | free qwen/qwen-2.5-72b-instruct | paid + qwen/qwen-2.5-72b-instruct:free | free qwen/qwen-2.5-7b-instruct | paid qwen/qwen-2.5-coder-32b-instruct | paid + qwen/qwen-2.5-coder-32b-instruct:free | free + rekaai/reka-flash-3:free | free undi95/remm-slerp-l2-13b | paid thedrummer/rocinante-12b | paid sophosympatheia/rogue-rose-103b-v0.2:free | free @@ -241,6 +287,10 @@ export interface IKBotOptions { sao10k/l3.1-euryale-70b | paid sao10k/l3.3-euryale-70b | paid raifle/sorcererlm-8x22b | paid + steelskull/l3.3-electra-r1-70b | paid + tokyotech-llm/llama-3.1-swallow-70b-instruct-v0.3 | paid + thedrummer/anubis-pro-105b-v1 | paid + thedrummer/skyfall-36b-v2 | paid undi95/toppy-m-7b | paid undi95/toppy-m-7b:free | free thedrummer/unslopnemo-12b | paid @@ -272,6 +322,8 @@ export interface IKBotOptions { gpt-4-turbo gpt-4-turbo-2024-04-09 gpt-4-turbo-preview + gpt-4.5-preview + gpt-4.5-preview-2025-02-27 gpt-4o gpt-4o-2024-05-13 gpt-4o-2024-08-06 @@ -285,13 +337,21 @@ export interface IKBotOptions { gpt-4o-mini-audio-preview-2024-12-17 gpt-4o-mini-realtime-preview gpt-4o-mini-realtime-preview-2024-12-17 + gpt-4o-mini-search-preview + gpt-4o-mini-search-preview-2025-03-11 gpt-4o-realtime-preview gpt-4o-realtime-preview-2024-10-01 gpt-4o-realtime-preview-2024-12-17 + gpt-4o-search-preview + gpt-4o-search-preview-2025-03-11 + o1 + o1-2024-12-17 o1-mini o1-mini-2024-09-12 o1-preview o1-preview-2024-09-12 + o3-mini + o3-mini-2025-01-31 omni-moderation-2024-09-26 omni-moderation-latest text-embedding-3-large diff --git a/packages/ai-tools/stats.json b/packages/ai-tools/stats.json deleted file mode 100644 index bfcd50dd..00000000 --- a/packages/ai-tools/stats.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "prompt_tokens": 14973, - "completion_tokens": 161, - "total_tokens": 15134 -} \ No newline at end of file diff --git a/packages/ai-tools/tools-template.md b/packages/ai-tools/tools-template.md deleted file mode 100644 index f0c56329..00000000 --- a/packages/ai-tools/tools-template.md +++ /dev/null @@ -1,31 +0,0 @@ -Email -- **send_email**(recipient: string|[string], subject?, body?) - -Search -- **google**(query: string) -- **serpapi**(query: string, engine?) - -Interact -- **send_email**(recipient: string|[string], subject?, body?) - -FS -- **list_files**(directory, pattern?) -- **read_files**(directory, pattern?) -- **remove_file**(path) -- **rename_file**(src, dst) -- **modify_project_files**([{path, content}...]) -- **create_file**({path, content}) -- **file_exists**({path}) -- **read_file**({path}) - -NPM -- **build_project**() -- **run_npm**(command, args?) -- **install_dependency**([dependencies...]) - -Git -- **init_repository**() -- **commit_files_git**([files...], message) - -Terminal -- **execute_command**(command, args?, cwd?, background?, window?, detached?) diff --git a/packages/ai-tools/tools.json b/packages/ai-tools/tools.json deleted file mode 100644 index 534fcd00..00000000 --- a/packages/ai-tools/tools.json +++ /dev/null @@ -1,423 +0,0 @@ -{ - "email": [ - { - "name": "send_email", - "description": "Sends an email", - "category": "email", - "parameters": { - "type": "object", - "properties": { - "recipient": { - "type": [ - "string", - "array" - ], - "items": { - "type": "string" - }, - "description": "The email address of the recipient(s). Can be a single email or an array of emails. For \"me\", use the default email address" - }, - "subject": { - "type": "string", - "description": "the subject", - "optional": true - }, - "body": { - "type": "string", - "description": "Markdown formatted body of the email", - "optional": true - } - }, - "required": [ - "url" - ] - } - } - ], - "search": [ - { - "name": "google", - "description": "Searches Google for the given query", - "category": "search", - "parameters": { - "type": "object", - "properties": { - "query": { - "type": "string" - } - }, - "required": [ - "query" - ] - } - }, - { - "name": "serpapi", - "description": "Searches Serpapi (finds locations (engine:google_local), places on the map (engine:google_maps) ) for the given query", - "category": "search", - "parameters": { - "type": "object", - "properties": { - "query": { - "type": "string" - }, - "engine": { - "type": "string", - "default": "google" - } - }, - "required": [ - "query" - ] - } - } - ], - "interact": [ - { - "name": "send_email", - "description": "Sends an email", - "category": "email", - "parameters": { - "type": "object", - "properties": { - "recipient": { - "type": [ - "string", - "array" - ], - "items": { - "type": "string" - }, - "description": "The email address of the recipient(s). Can be a single email or an array of emails. For \"me\", use the default email address" - }, - "subject": { - "type": "string", - "description": "the subject", - "optional": true - }, - "body": { - "type": "string", - "description": "Markdown formatted body of the email", - "optional": true - } - }, - "required": [ - "url" - ] - } - } - ], - "fs": [ - { - "name": "list_files", - "description": "List all files in a directory", - "category": "fs", - "parameters": { - "type": "object", - "properties": { - "directory": { - "type": "string" - }, - "pattern": { - "type": "string", - "optional": true - } - }, - "required": [ - "directory" - ] - } - }, - { - "name": "read_files", - "description": "Reads files in a directory with a given pattern", - "category": "fs", - "parameters": { - "type": "object", - "properties": { - "directory": { - "type": "string" - }, - "pattern": { - "type": "string", - "optional": true - } - }, - "required": [ - "directory" - ] - } - }, - { - "name": "remove_file", - "description": "Remove a file at given path", - "category": "fs", - "parameters": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - }, - "required": [ - "path" - ] - } - }, - { - "name": "rename_file", - "description": "Rename or move a file or directory", - "category": "fs", - "parameters": { - "type": "object", - "properties": { - "src": { - "type": "string" - }, - "dst": { - "type": "string" - } - }, - "required": [ - "path" - ] - } - }, - { - "name": "modify_project_files", - "description": "Modify existing project files", - "category": "fs", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string", - "description": "base64 encoded string" - } - }, - "required": [ - "path", - "content" - ] - } - } - }, - "required": [ - "files" - ] - } - }, - { - "name": "create_file", - "description": "Creates a file, given a path and content", - "category": "fs", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "content": { - "type": "string", - "description": "base64 encoded string" - } - } - } - }, - "required": [ - "file" - ] - } - }, - { - "name": "file_exists", - "description": "check if a file or folder exists", - "category": "fs", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - }, - { - "name": "read_file", - "description": "read a file, at given a path", - "category": "fs", - "parameters": { - "type": "object", - "properties": { - "file": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - } - } - }, - "required": [ - "file" - ] - } - } - ], - "npm": [ - { - "name": "build_project", - "description": "Build project using pnpm build command", - "category": "npm", - "parameters": { - "type": "object", - "properties": {}, - "required": [] - } - }, - { - "name": "run_npm", - "description": "Run an npm/pnpm command", - "category": "npm", - "parameters": { - "type": "object", - "properties": { - "command": { - "type": "string", - "description": "Command to run (e.g. install, test, etc)" - }, - "args": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Additional arguments for the command", - "optional": true - } - }, - "required": [ - "command" - ] - } - }, - { - "name": "install_dependency", - "description": "Install a dependency using npm", - "category": "npm", - "parameters": { - "type": "object", - "properties": { - "dependencies": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "dependencies" - ] - } - } - ], - "git": [ - { - "name": "init_repository", - "description": "Initialize a new git repository", - "category": "git", - "parameters": { - "type": "object", - "properties": {}, - "required": [] - } - }, - { - "name": "commit_files_git", - "description": "Commit files using git", - "category": "git", - "parameters": { - "type": "object", - "properties": { - "files": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } - }, - "required": [ - "files" - ] - } - } - ], - "terminal": [ - { - "name": "execute_command", - "description": "Execute a terminal command and capture output", - "category": "terminal", - "parameters": { - "type": "object", - "properties": { - "command": { - "type": "string", - "description": "Command to execute" - }, - "args": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Command arguments", - "optional": true - }, - "cwd": { - "type": "string", - "description": "Working directory for command execution", - "optional": true - }, - "background": { - "type": "boolean", - "description": "Run command in background (non-blocking)", - "optional": true - }, - "window": { - "type": "boolean", - "description": "Open command in new terminal window", - "optional": true - }, - "detached": { - "type": "boolean", - "description": "Run process detached from parent", - "optional": true - } - }, - "required": [ - "command" - ] - } - } - ] -} \ No newline at end of file diff --git a/packages/ai-tools/tools.json.md b/packages/ai-tools/tools.json.md deleted file mode 100644 index 3796f106..00000000 --- a/packages/ai-tools/tools.json.md +++ /dev/null @@ -1,39 +0,0 @@ -## email -- send_email(?recipient, ?subject, ?body): Sends an email - -## search -- google(query): Searches Google for the given query -- serpapi(query, ?engine): Searches Serpapi (finds locations (engine:google_local), places on the map (engine:google_maps) ) for the given query - -## interact -- send_email(?recipient, ?subject, ?body): Sends an email - -## fs -- list_files(directory, ?pattern): List all files in a directory -- read_files(directory, ?pattern): Reads files in a directory with a given pattern -- remove_file(path): Remove a file at given path -- rename_file(?src, ?dst): Rename or move a file or directory -- modify_project_files(files): Modify existing project files -- create_file(file): Creates a file, given a path and content -- file_exists(file): check if a file or folder exists -- read_file(file): read a file, at given a path - -## npm -- build_project(): Build project using pnpm build command -- run_npm(command, ?args): Run an npm/pnpm command -- install_dependency(dependencies): Install a dependency using npm - -## git -- init_repository(): Initialize a new git repository -- commit_files_git(files, ?message): Commit files using git - -## terminal -- execute_command(command, ?args, ?cwd, ?background, ?window, ?detached): Execute a terminal command and capture output - -Preferred order: - -1. create/modify files, using modify_project_files for multiple files at once -2. install dependencies -3. excecute tools -4. create documentation -5. init git, add to git