autoclaw 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +19 -8
  2. package/dist/index.js +38 -20
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -43,18 +43,29 @@ npm update -g autoclaw
43
43
 
44
44
  ## Configuration
45
45
 
46
- AutoClaw uses a global JSON configuration file located at `~/.autoclaw/setting.json`.
47
- You can also use a local `.env` file in your current directory to override global settings.
46
+ AutoClaw uses a hierarchical configuration system.
48
47
 
49
- Priority order:
50
- 1. Command-line arguments (e.g., `-m`)
51
- 2. Local `.env` file
52
- 3. Global config (`~/.autoclaw/setting.json`)
48
+ **Priority Order (Highest to Lowest):**
49
+ 1. **CLI Arguments**: (e.g., `-m gpt-4o`)
50
+ 2. **Environment Variables**: (`OPENAI_API_KEY`, `.env` file)
51
+ 3. **Project Config**: (`./.autoclaw/setting.json` in current directory)
52
+ 4. **Global Config**: (`~/.autoclaw/setting.json`)
53
53
 
54
- Supported Configuration Keys:
54
+ ### Supported Configuration Keys (JSON)
55
55
  - `apiKey`: Your API Key.
56
56
  - `baseUrl`: Custom Base URL.
57
- - `model`: Default model to use (default: `gpt-4o`).
57
+ - `model`: Default model to use.
58
+
59
+ ### Project-Level Config (Example)
60
+ Create a file at `.autoclaw/setting.json`:
61
+ ```json
62
+ {
63
+ "model": "gpt-3.5-turbo",
64
+ "baseUrl": "https://api.example.com/v1"
65
+ }
66
+ ```
67
+
68
+ > **⚠️ Security Warning**: If you store your `apiKey` in `.autoclaw/setting.json`, make sure to add `.autoclaw/` to your `.gitignore` file to prevent leaking secrets!
58
69
 
59
70
  ## License
60
71
 
package/dist/index.js CHANGED
@@ -7,26 +7,39 @@ import { Agent } from './agent.js';
7
7
  import * as fs from 'fs';
8
8
  import * as path from 'path';
9
9
  import * as os from 'os';
10
- const CONFIG_DIR = path.join(os.homedir(), '.autoclaw');
11
- const CONFIG_FILE = path.join(CONFIG_DIR, 'setting.json');
12
- function loadGlobalConfig() {
13
- if (fs.existsSync(CONFIG_FILE)) {
10
+ import { fileURLToPath } from 'url';
11
+ const GLOBAL_CONFIG_DIR = path.join(os.homedir(), '.autoclaw');
12
+ const GLOBAL_CONFIG_FILE = path.join(GLOBAL_CONFIG_DIR, 'setting.json');
13
+ const LOCAL_CONFIG_FILE = path.join(process.cwd(), '.autoclaw', 'setting.json');
14
+ function loadJsonConfig(filePath) {
15
+ if (fs.existsSync(filePath)) {
14
16
  try {
15
- return JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf-8'));
17
+ return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
16
18
  }
17
19
  catch (e) {
18
- console.error(chalk.red("Error reading global config file."));
20
+ console.error(chalk.yellow(`Warning: Failed to parse config file at ${filePath}`));
19
21
  }
20
22
  }
21
23
  return {};
22
24
  }
23
25
  // Load local env vars
24
26
  dotenv.config();
27
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
28
+ // In dist/index.js, package.json is usually up one level in the root
29
+ const pkgPath = path.join(__dirname, '..', 'package.json');
30
+ let version = '1.0.2';
31
+ try {
32
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
33
+ version = pkg.version;
34
+ }
35
+ catch (e) {
36
+ // Fallback if package.json not found in expected location
37
+ }
25
38
  const program = new Command();
26
39
  program
27
40
  .name('autoclaw')
28
41
  .description('A lightweight AI agent CLI tool')
29
- .version('1.0.1');
42
+ .version(version);
30
43
  program
31
44
  .command('setup')
32
45
  .description('Run the interactive setup wizard to configure API keys')
@@ -43,8 +56,8 @@ program
43
56
  program.parse(process.argv);
44
57
  async function runSetup() {
45
58
  console.log(chalk.bold.cyan("AutoClaw Setup Wizard 🦞\n"));
46
- console.log(chalk.dim(`Config will be saved to: ${CONFIG_FILE}`));
47
- const currentConfig = loadGlobalConfig();
59
+ console.log(chalk.dim(`Config will be saved to: ${GLOBAL_CONFIG_FILE}`));
60
+ const currentConfig = loadJsonConfig(GLOBAL_CONFIG_FILE);
48
61
  const answers = await inquirer.prompt([
49
62
  {
50
63
  type: 'password',
@@ -73,11 +86,11 @@ async function runSetup() {
73
86
  model: answers.model
74
87
  };
75
88
  try {
76
- if (!fs.existsSync(CONFIG_DIR)) {
77
- fs.mkdirSync(CONFIG_DIR, { recursive: true });
89
+ if (!fs.existsSync(GLOBAL_CONFIG_DIR)) {
90
+ fs.mkdirSync(GLOBAL_CONFIG_DIR, { recursive: true });
78
91
  }
79
- fs.writeFileSync(CONFIG_FILE, JSON.stringify(newConfig, null, 2), { mode: 0o600 });
80
- console.log(chalk.green(`\n✅ Configuration saved to ${CONFIG_FILE}`));
92
+ fs.writeFileSync(GLOBAL_CONFIG_FILE, JSON.stringify(newConfig, null, 2), { mode: 0o600 });
93
+ console.log(chalk.green(`\n✅ Configuration saved to ${GLOBAL_CONFIG_FILE}`));
81
94
  console.log(chalk.cyan("You can now run 'autoclaw' to start using the agent."));
82
95
  }
83
96
  catch (error) {
@@ -86,12 +99,17 @@ async function runSetup() {
86
99
  }
87
100
  async function runChat(options) {
88
101
  console.log(chalk.bold.cyan("Welcome to AutoClaw CLI 🦞"));
89
- // 1. Load Global (JSON)
90
- const globalConfig = loadGlobalConfig();
91
- // 2. Resolve final values (Priority: CLI > Env > Global JSON > Default)
92
- let apiKey = process.env.OPENAI_API_KEY || globalConfig.apiKey;
93
- let baseURL = process.env.OPENAI_BASE_URL || globalConfig.baseUrl;
94
- let model = options.model || process.env.OPENAI_MODEL || globalConfig.model || 'gpt-4o';
102
+ // 1. Load Global JSON
103
+ const globalConfig = loadJsonConfig(GLOBAL_CONFIG_FILE);
104
+ // 2. Load Local JSON (Project Level)
105
+ const localConfig = loadJsonConfig(LOCAL_CONFIG_FILE);
106
+ if (Object.keys(localConfig).length > 0) {
107
+ console.log(chalk.dim(`Loaded project config from ${LOCAL_CONFIG_FILE}`));
108
+ }
109
+ // 3. Merge: CLI > Env > Local JSON > Global JSON
110
+ let apiKey = process.env.OPENAI_API_KEY || localConfig.apiKey || globalConfig.apiKey;
111
+ let baseURL = process.env.OPENAI_BASE_URL || localConfig.baseUrl || globalConfig.baseUrl;
112
+ let model = options.model || process.env.OPENAI_MODEL || localConfig.model || globalConfig.model || 'gpt-4o';
95
113
  if (!apiKey) {
96
114
  console.log(chalk.yellow("API Key not found."));
97
115
  const { doSetup } = await inquirer.prompt([
@@ -104,7 +122,7 @@ async function runChat(options) {
104
122
  ]);
105
123
  if (doSetup) {
106
124
  await runSetup();
107
- const newConfig = loadGlobalConfig();
125
+ const newConfig = loadJsonConfig(GLOBAL_CONFIG_FILE);
108
126
  apiKey = newConfig.apiKey;
109
127
  baseURL = newConfig.baseUrl;
110
128
  model = options.model || newConfig.model || 'gpt-4o';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "autoclaw",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -33,7 +33,7 @@
33
33
  "dependencies": {
34
34
  "chalk": "^5.6.2",
35
35
  "commander": "^14.0.3",
36
- "dotenv": "^17.2.4",
36
+ "dotenv": "^16.4.7",
37
37
  "inquirer": "^13.2.2",
38
38
  "openai": "^6.18.0",
39
39
  "ora": "^9.3.0"