@renxqoo/renx-code 0.0.5 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,91 +1,107 @@
1
- # OpenTUI Agent CLI (React + Bun)
1
+ # Renx
2
2
 
3
- Initialized from the latest OpenTUI React template:
3
+ `renx` is a terminal AI coding assistant.
4
4
 
5
- ```bash
6
- bun create tui --template react opentui-agent-cli
7
- ```
5
+ - npm package: `@renxqoo/renx-code`
6
+ - command: `renx`
7
+
8
+ ## Install
8
9
 
9
- Current package versions:
10
+ Requirements:
10
11
 
11
- - `@opentui/core`: `0.1.84`
12
- - `@opentui/react`: `0.1.84`
13
- - `react`: `19.2.4`
12
+ - Node.js `20+`
14
13
 
15
- ## Run
14
+ Install globally:
16
15
 
17
16
  ```bash
18
- bun dev
17
+ npm i -g @renxqoo/renx-code --registry=https://registry.npmjs.org
19
18
  ```
20
19
 
21
- Optional hot reload (less stable for interactive TUI signal handling):
20
+ Start:
22
21
 
23
22
  ```bash
24
- bun run dev:watch
23
+ renx
25
24
  ```
26
25
 
27
- ## What is implemented
26
+ No separate Bun installation is required for published npm installs.
28
27
 
29
- - Agent-style CLI chat layout (header, conversation panel, prompt input)
30
- - Built-in commands: `/help`, `/clear`, `/exit`
31
- - Keyboard shortcuts: `Esc` (stop current response when thinking, otherwise clear input), `Ctrl+L` (clear conversation)
32
- - Simulated async agent reply flow
28
+ ## Basic Usage
33
29
 
34
- ## Main file
30
+ Run `renx` inside any project directory:
35
31
 
36
- - `src/index.tsx`
32
+ ```bash
33
+ renx
34
+ ```
37
35
 
38
- ## Configuration
36
+ `renx` uses the current terminal directory as the workspace by default.
37
+
38
+ Common things you can do:
39
+
40
+ - read and explain code
41
+ - modify files
42
+ - investigate errors
43
+ - work inside the current project directory
44
+
45
+ Built-in commands:
39
46
 
40
- OpenTUI Agent CLI uses the shared Renx config system.
47
+ - `/help`
48
+ - `/clear`
49
+ - `/exit`
41
50
 
42
- Effective precedence is:
51
+ Keyboard shortcuts:
43
52
 
44
- 1. Existing process environment variables plus values loaded from `.env` / `.env.development`
45
- 2. Project config: `<workspace>/.renx/config.json`
46
- 3. Global config: `RENX_HOME/config.json`
47
- 4. Built-in defaults
53
+ - `Esc`: stop the current response, or clear the current input
54
+ - `Ctrl + L`: clear the current conversation
48
55
 
49
- Directory-related state is managed from a single root:
56
+ ## Configuration
57
+
58
+ Configuration priority:
59
+
60
+ 1. process environment variables and `.env` / `.env.development`
61
+ 2. project config: `<workspace>/.renx/config.json`
62
+ 3. global config: `RENX_HOME/config.json`
63
+ 4. built-in defaults
50
64
 
51
- - `RENX_HOME` defaults to `~/.renx`
52
- - `RENX_HOME/config.json` for global config
53
- - `RENX_HOME/logs/` for log files
54
- - `RENX_HOME/storage/` for file-history storage
55
- - `RENX_HOME/task/` for task data
56
- - `RENX_HOME/data.db` for the shared SQLite database
65
+ Default user data locations:
57
66
 
58
- ## Supported Environment Variables
67
+ - `RENX_HOME`, default: `~/.renx`
68
+ - `RENX_HOME/config.json`
69
+ - `RENX_HOME/logs/`
70
+ - `RENX_HOME/storage/`
71
+ - `RENX_HOME/task/`
72
+ - `RENX_HOME/data.db`
59
73
 
60
- Application/runtime variables:
74
+ ## Environment Variables
61
75
 
62
- - `RENX_HOME`: overrides the user-level Renx home directory
63
- - `AGENT_MODEL`: default model id
64
- - `AGENT_MAX_STEPS`: max steps per run
65
- - `AGENT_MAX_RETRY_COUNT`: agent retry count
66
- - `AGENT_TOOL_CONFIRMATION_MODE`: `manual`, `auto-approve`, or `auto-deny`
67
- - `AGENT_CONVERSATION_ID`: fixed conversation id for the CLI runtime
68
- - `AGENT_SESSION_ID`: fallback session id when `AGENT_CONVERSATION_ID` is unset
76
+ Runtime:
69
77
 
70
- Logging variables:
78
+ - `RENX_HOME`
79
+ - `AGENT_MODEL`
80
+ - `AGENT_MAX_STEPS`
81
+ - `AGENT_MAX_RETRY_COUNT`
82
+ - `AGENT_TOOL_CONFIRMATION_MODE`
83
+ - `AGENT_CONVERSATION_ID`
84
+ - `AGENT_SESSION_ID`
71
85
 
72
- - `AGENT_LOG_LEVEL`: `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`, or `FATAL`
73
- - `AGENT_LOG_FORMAT`: `pretty` or `json`
74
- - `AGENT_LOG_CONSOLE`: enable/disable console logging
75
- - `AGENT_LOG_FILE_ENABLED`: enable/disable file logging
86
+ Logging:
76
87
 
77
- File history variables:
88
+ - `AGENT_LOG_LEVEL`
89
+ - `AGENT_LOG_FORMAT`
90
+ - `AGENT_LOG_CONSOLE`
91
+ - `AGENT_LOG_FILE_ENABLED`
92
+
93
+ File history:
78
94
 
79
95
  - `AGENT_FILE_HISTORY_ENABLED`
80
96
  - `AGENT_FILE_HISTORY_MAX_PER_FILE`
81
97
  - `AGENT_FILE_HISTORY_MAX_AGE_DAYS`
82
98
  - `AGENT_FILE_HISTORY_MAX_TOTAL_MB`
83
99
 
84
- Model provider API keys are still provided through their own env vars such as `GLM_API_KEY`.
100
+ Provider API keys are still passed through their own environment variables, for example:
85
101
 
86
- ## Config File Shape
102
+ - `GLM_API_KEY`
87
103
 
88
- Global and project config files use the same JSON structure:
104
+ ## Config Example
89
105
 
90
106
  ```json
91
107
  {
@@ -111,4 +127,14 @@ Global and project config files use the same JSON structure:
111
127
  }
112
128
  ```
113
129
 
114
- There are no per-directory config fields anymore. All user-level paths are derived from `RENX_HOME`.
130
+ Project config example:
131
+
132
+ ```text
133
+ your-project/.renx/config.json
134
+ ```
135
+
136
+ Global config example:
137
+
138
+ ```text
139
+ ~/.renx/config.json
140
+ ```
package/bin/renx.cjs CHANGED
@@ -8,7 +8,7 @@ const packageRoot = path.resolve(__dirname, "..");
8
8
  const entryPath = path.join(packageRoot, "src", "index.tsx");
9
9
  const packagedRepoRoot = path.join(packageRoot, "vendor", "agent-root");
10
10
  const localRepoRoot = path.resolve(packageRoot, "..");
11
- const bunExecutable = process.env.RENX_BUN_PATH || "bun";
11
+ const nodeExecutable = process.env.RENX_NODE_PATH || process.execPath;
12
12
 
13
13
  const hasAgentSourceRoot = root =>
14
14
  fs.existsSync(path.join(root, "src", "providers", "index.ts")) &&
@@ -28,7 +28,16 @@ if (!fs.existsSync(entryPath)) {
28
28
  process.exit(1);
29
29
  }
30
30
 
31
- const result = childProcess.spawnSync(bunExecutable, [entryPath, ...process.argv.slice(2)], {
31
+ let tsxCliPath;
32
+ try {
33
+ tsxCliPath = require.resolve("tsx/cli", { paths: [packageRoot] });
34
+ } catch (error) {
35
+ const message = error instanceof Error ? error.message : String(error);
36
+ console.error(`Could not resolve tsx runtime from this installation: ${message}`);
37
+ process.exit(1);
38
+ }
39
+
40
+ const result = childProcess.spawnSync(nodeExecutable, [tsxCliPath, entryPath, ...process.argv.slice(2)], {
32
41
  cwd: process.cwd(),
33
42
  stdio: "inherit",
34
43
  env: {
@@ -39,11 +48,7 @@ const result = childProcess.spawnSync(bunExecutable, [entryPath, ...process.argv
39
48
  });
40
49
 
41
50
  if (result.error) {
42
- if (result.error.code === "ENOENT") {
43
- console.error("Bun is required to run renx. Install Bun first: https://bun.sh");
44
- } else {
45
- console.error(result.error.message);
46
- }
51
+ console.error(result.error.message);
47
52
  process.exit(1);
48
53
  }
49
54
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@renxqoo/renx-code",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "module": "src/index.tsx",
5
5
  "type": "module",
6
6
  "private": false,
@@ -15,8 +15,7 @@
15
15
  "tsconfig.json"
16
16
  ],
17
17
  "engines": {
18
- "node": ">=20.0.0",
19
- "bun": ">=1.1.0"
18
+ "node": ">=20.0.0"
20
19
  },
21
20
  "peerDependencies": {
22
21
  "typescript": "^5.9.3"
@@ -24,6 +23,19 @@
24
23
  "dependencies": {
25
24
  "@opentui/core": "^0.1.84",
26
25
  "@opentui/react": "^0.1.84",
27
- "react": "^19.2.4"
26
+ "@vscode/ripgrep": "^1.17.0",
27
+ "diff": "^8.0.3",
28
+ "dotenv": "^17.3.1",
29
+ "js-tiktoken": "^1.0.21",
30
+ "log-update": "^6.1.0",
31
+ "marked": "^15.0.12",
32
+ "marked-terminal": "^7.3.0",
33
+ "minimatch": "^10.2.4",
34
+ "react": "^19.2.4",
35
+ "shell-quote": "^1.8.3",
36
+ "strip-ansi": "^7.2.0",
37
+ "uuid": "^13.0.0",
38
+ "zod": "^4.3.6",
39
+ "tsx": "^4.21.0"
28
40
  }
29
41
  }
@@ -1,4 +1,4 @@
1
- import { readdir } from 'node:fs/promises';
1
+ import { readdir, stat } from 'node:fs/promises';
2
2
  import { join, relative } from 'node:path';
3
3
 
4
4
  import { resolveWorkspaceRoot } from '../agent/runtime/source-modules';
@@ -40,17 +40,15 @@ const visitDirectory = async (
40
40
  continue;
41
41
  }
42
42
 
43
- const stat = await Bun.file(absolutePath)
44
- .stat()
45
- .catch(() => undefined);
46
- if (!stat || !stat.isFile()) {
43
+ const fileStat = await stat(absolutePath).catch(() => undefined);
44
+ if (!fileStat || !fileStat.isFile()) {
47
45
  continue;
48
46
  }
49
47
 
50
48
  output.push({
51
49
  relativePath: relative(root, absolutePath),
52
50
  absolutePath,
53
- size: stat.size,
51
+ size: fileStat.size,
54
52
  });
55
53
  }
56
54
  };
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { LLMTool, ToolConcurrencyMode, ToolExecutionContext } from './types';
2
+ import type { LLMTool, ToolConcurrencyMode, ToolExecutionContext } from './types';
3
3
  import { ToolExecutionError } from './error';
4
4
 
5
5
  export type ToolParameterSchema = z.ZodType;
@@ -6,7 +6,7 @@ import * as os from 'node:os';
6
6
  import * as path from 'node:path';
7
7
  import stripAnsi from 'strip-ansi';
8
8
  import { z } from 'zod';
9
- import { BaseTool, ToolResult } from './base-tool';
9
+ import { BaseTool, type ToolResult } from './base-tool';
10
10
  import { ToolExecutionError } from './error';
11
11
  import { evaluateBashPolicy, type BashPolicyEffect, type BashPolicyMode } from './bash-policy';
12
12
  import type { ToolExecutionContext } from './types';
@@ -2,7 +2,7 @@ import * as fs from 'node:fs/promises';
2
2
  import { createHash } from 'node:crypto';
3
3
  import { createTwoFilesPatch } from 'diff';
4
4
  import { z } from 'zod';
5
- import { BaseTool, ToolConfirmDetails, ToolResult } from './base-tool';
5
+ import { BaseTool, type ToolConfirmDetails, type ToolResult } from './base-tool';
6
6
  import { ToolExecutionError } from './error';
7
7
  import {
8
8
  assessPathAccess,
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { BaseTool, ToolConfirmDetails, ToolResult } from './base-tool';
2
+ import { BaseTool, type ToolConfirmDetails, type ToolResult } from './base-tool';
3
3
  import { ToolExecutionError } from './error';
4
4
  import {
5
5
  assessPathAccess,
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { BaseTool, ToolConfirmDetails, ToolResult } from './base-tool';
2
+ import { BaseTool, type ToolConfirmDetails, type ToolResult } from './base-tool';
3
3
  import { ToolExecutionError } from './error';
4
4
  import {
5
5
  assessPathAccess,
@@ -1,7 +1,7 @@
1
1
  import * as fs from 'node:fs/promises';
2
2
  import { createHash } from 'node:crypto';
3
3
  import { z } from 'zod';
4
- import { BaseTool, ToolConfirmDetails, ToolResult } from './base-tool';
4
+ import { BaseTool, type ToolConfirmDetails, type ToolResult } from './base-tool';
5
5
  import { ToolExecutionError } from './error';
6
6
  import {
7
7
  assessPathAccess,
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { BaseTool, ToolConfirmDetails, ToolResult } from './base-tool';
2
+ import { BaseTool, type ToolConfirmDetails, type ToolResult } from './base-tool';
3
3
  import { ToolExecutionError } from './error';
4
4
  import { collectFilesByGlob, DEFAULT_IGNORE_GLOBS, resolveSearchRoot } from './search/common';
5
5
  import {
@@ -3,9 +3,9 @@ import * as path from 'node:path';
3
3
  import * as readline from 'node:readline';
4
4
  import { rgPath as vscodeRgPath } from '@vscode/ripgrep';
5
5
  import { z } from 'zod';
6
- import { BaseTool, ToolConfirmDetails, ToolResult } from './base-tool';
6
+ import { BaseTool, type ToolConfirmDetails, type ToolResult } from './base-tool';
7
7
  import { ToolExecutionError } from './error';
8
- import { ToolExecutionContext } from './types';
8
+ import type { ToolExecutionContext } from './types';
9
9
  import { DEFAULT_IGNORE_GLOBS, resolveSearchRoot } from './search/common';
10
10
  import {
11
11
  assessPathAccess,
@@ -2,7 +2,7 @@ import { z } from 'zod';
2
2
  import * as ts from 'typescript';
3
3
  import * as path from 'node:path';
4
4
  import * as fs from 'node:fs';
5
- import { BaseTool, ToolResult } from './base-tool';
5
+ import { BaseTool, type ToolResult } from './base-tool';
6
6
  import { ToolExecutionError } from './error';
7
7
  import { ensurePathWithinAllowed, normalizeAllowedDirectories } from './path-security';
8
8
  import { LSP_TOOL_DESCRIPTION } from './tool-prompts';
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { BaseTool, ToolResult } from './base-tool';
2
+ import { BaseTool, type ToolResult } from './base-tool';
3
3
  import { ToolExecutionError } from './error';
4
4
  import { formatSkillForContext } from './skill/parser';
5
5
  import { getSkillLoader, initializeSkillLoader } from './skill/loader';
@@ -4,16 +4,15 @@
4
4
  */
5
5
 
6
6
  import {
7
- LLMTool,
8
- ToolCall,
9
- ToolConcurrencyPolicy,
10
- ToolConfirmInfo,
11
- ToolPolicyCheckInfo,
12
- ToolPolicyDecision,
13
- ToolExecutionContext,
7
+ type LLMTool,
8
+ type ToolCall,
9
+ type ToolConcurrencyPolicy,
10
+ type ToolConfirmInfo,
11
+ type ToolPolicyCheckInfo,
12
+ type ToolPolicyDecision,
13
+ type ToolExecutionContext,
14
14
  } from './types';
15
- import { BaseTool, ToolConfirmDetails } from './base-tool';
16
- import { ToolResult } from './base-tool';
15
+ import { BaseTool, type ToolConfirmDetails, type ToolResult } from './base-tool';
17
16
  import {
18
17
  EmptyToolNameError,
19
18
  InvalidArgumentsError,
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { BaseTool, ToolResult } from './base-tool';
2
+ import { BaseTool, type ToolResult } from './base-tool';
3
3
  import { ToolExecutionError } from './error';
4
4
  import { WEB_FETCH_TOOL_DESCRIPTION } from './tool-prompts';
5
5
  import type { ToolExecutionContext } from './types';
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { BaseTool, ToolResult } from './base-tool';
2
+ import { BaseTool, type ToolResult } from './base-tool';
3
3
  import { ToolExecutionError } from './error';
4
4
  import { WEB_SEARCH_TOOL_DESCRIPTION } from './tool-prompts';
5
5
  import type { ToolExecutionContext } from './types';