cliclaw 1.0.5 → 1.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/bin/cli.js CHANGED
@@ -9,6 +9,13 @@ const os = require('os')
9
9
 
10
10
  const PKG_DIR = path.resolve(__dirname, '..')
11
11
 
12
+ // User data directory — persists across npm updates
13
+ // Windows: %APPDATA%\cliclaw | others: ~/.cliclaw
14
+ const USER_DIR = process.env.CLICLAW_DIR ||
15
+ (os.platform() === 'win32'
16
+ ? path.join(process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming'), 'cliclaw')
17
+ : path.join(os.homedir(), '.cliclaw'))
18
+
12
19
  // ─── colors ──────────────────────────────────────────────────────────────────
13
20
  const c = {
14
21
  reset:'\x1b[0m', bold:'\x1b[1m', cyan:'\x1b[36m',
@@ -154,10 +161,14 @@ async function cmdSetup() {
154
161
 
155
162
  // ─── config wizard ────────────────────────────────────────────────────────────
156
163
  async function runConfigWizard() {
157
- const envFile = path.join(PKG_DIR, '.env')
164
+ if (!fs.existsSync(USER_DIR)) fs.mkdirSync(USER_DIR, { recursive: true })
165
+ const envFile = path.join(USER_DIR, '.env')
158
166
  const existing = {}
159
- if (fs.existsSync(envFile)) {
160
- fs.readFileSync(envFile, 'utf8').split('\n').forEach(l => {
167
+ // Also check legacy pkg-dir .env for migration
168
+ const legacyEnv = path.join(PKG_DIR, '.env')
169
+ const srcEnv = fs.existsSync(envFile) ? envFile : (fs.existsSync(legacyEnv) ? legacyEnv : null)
170
+ if (srcEnv) {
171
+ fs.readFileSync(srcEnv, 'utf8').split('\n').forEach(l => {
161
172
  const [k, ...v] = l.split('=')
162
173
  if (k && v.length) existing[k.trim()] = v.join('=').trim()
163
174
  })
@@ -187,20 +198,21 @@ async function runConfigWizard() {
187
198
  const permMode = permChoice === '2' ? 'session' : permChoice === '3' ? 'ask' : 'auto'
188
199
  ok(`Permission mode: ${permMode}`)
189
200
 
190
- const dataDir = path.join(PKG_DIR, 'data')
201
+ const dataDir = existing.DATA_DIR || path.join(USER_DIR, 'data')
191
202
  let envContent = `TELEGRAM_BOT_TOKEN=${token}\n`
192
203
  if (forumId) envContent += `FORUM_GROUP_ID=${forumId}\n`
193
204
  envContent += `PERMISSION_MODE=${permMode}\n`
194
205
  envContent += `DATA_DIR=${dataDir}\n`
195
206
  fs.writeFileSync(envFile, envContent, 'utf8')
196
- ok(`.env saved`)
207
+ ok(`.env saved → ${envFile}`)
197
208
  }
198
209
 
199
210
  // ─── config (open .env in editor) ────────────────────────────────────────────
200
211
  function cmdConfig() {
201
- const envFile = path.join(PKG_DIR, '.env')
212
+ const envFile = path.join(USER_DIR, '.env')
202
213
  if (!fs.existsSync(envFile)) {
203
- warn('.env not found. Run: cliclaw setup')
214
+ warn(`.env not found at ${envFile}`)
215
+ warn('Run: cliclaw setup')
204
216
  process.exit(1)
205
217
  }
206
218
  const platform = os.platform()
@@ -17,6 +17,7 @@ module.exports = {
17
17
  },
18
18
  watch: false,
19
19
  autorestart: true,
20
+ restart_delay: 5000,
20
21
  max_memory_restart: '300M',
21
22
  error_file: path.join(__dirname, 'logs/error.log'),
22
23
  out_file: path.join(__dirname, 'logs/out.log'),
package/index.ts CHANGED
@@ -25,4 +25,13 @@ if (config.FORUM_GROUP_ID) {
25
25
 
26
26
  bot.start({
27
27
  onStart: (info) => console.log(`✅ Bot @${info.username} online!`),
28
+ }).catch(async (e) => {
29
+ const code = (e as any)?.error_code ?? (e as any)?.code
30
+ if (code === 409) {
31
+ console.warn('⚠️ 409 Conflict — outra instância ativa. Aguardando 35s para o long-poll expirar...')
32
+ await new Promise(r => setTimeout(r, 35_000))
33
+ } else {
34
+ console.error('[OpenClaw] Erro fatal:', e)
35
+ }
36
+ process.exit(1)
28
37
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cliclaw",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "Telegram bot bridging AI CLIs (Claude Code, Codex) to Forum Topics",
5
5
  "main": "index.ts",
6
6
  "scripts": {
package/src/config.ts CHANGED
@@ -1,6 +1,7 @@
1
- import { existsSync, readFileSync } from 'fs'
1
+ import { existsSync, readFileSync, mkdirSync } from 'fs'
2
2
  import { execSync } from 'child_process'
3
3
  import { join } from 'path'
4
+ import { homedir } from 'os'
4
5
 
5
6
  export type AgentName = 'claude' | 'codex'
6
7
  export type PermissionMode = 'auto' | 'session' | 'ask'
@@ -14,8 +15,14 @@ export interface Config {
14
15
  availableAgents: AgentName[]
15
16
  }
16
17
 
17
- // Resolve package root relative to this file (works for global npm install too)
18
- // src/config.ts is 1 level below package root
18
+ // User data directory persists across npm updates
19
+ // Windows: %APPDATA%\cliclaw | others: ~/.cliclaw
20
+ export const USER_DIR = process.env.CLICLAW_DIR ||
21
+ (process.platform === 'win32'
22
+ ? join(process.env.APPDATA || join(homedir(), 'AppData', 'Roaming'), 'cliclaw')
23
+ : join(homedir(), '.cliclaw'))
24
+
25
+ // Legacy: package root .env (used before 1.0.6)
19
26
  const PKG_ROOT = join(__dirname, '..')
20
27
 
21
28
  function checkAgents(): AgentName[] {
@@ -31,8 +38,9 @@ function checkAgents(): AgentName[] {
31
38
  }
32
39
 
33
40
  export function loadConfig(): Config {
34
- // CLICLAW_ENV env var allows override; otherwise resolves to <pkg-root>/.env
35
- const envFile = process.env.CLICLAW_ENV || join(PKG_ROOT, '.env')
41
+ // Resolution order: CLICLAW_ENV USER_DIR/.env PKG_ROOT/.env (legacy)
42
+ const envFile = process.env.CLICLAW_ENV ||
43
+ (existsSync(join(USER_DIR, '.env')) ? join(USER_DIR, '.env') : join(PKG_ROOT, '.env'))
36
44
  if (existsSync(envFile)) {
37
45
  const content = readFileSync(envFile, 'utf-8')
38
46
  for (const line of content.split('\n')) {
@@ -53,7 +61,7 @@ export function loadConfig(): Config {
53
61
 
54
62
  const config: Config = {
55
63
  TELEGRAM_BOT_TOKEN: process.env.TELEGRAM_BOT_TOKEN || '',
56
- DATA_DIR: process.env.DATA_DIR || join(PKG_ROOT, 'data'),
64
+ DATA_DIR: process.env.DATA_DIR || join(USER_DIR, 'data'),
57
65
  FORUM_GROUP_ID: process.env.FORUM_GROUP_ID || '',
58
66
  TELEGRAM_ADMIN_IDS: (process.env.TELEGRAM_ADMIN_IDS || '')
59
67
  .split(',').map(id => id.trim()).filter(Boolean),
@@ -62,7 +70,11 @@ export function loadConfig(): Config {
62
70
  }
63
71
 
64
72
  if (!config.TELEGRAM_BOT_TOKEN) {
65
- throw new Error(`TELEGRAM_BOT_TOKEN not set in .env (looked at: ${envFile})`)
73
+ throw new Error(
74
+ `TELEGRAM_BOT_TOKEN not set.\n` +
75
+ `Run: cliclaw setup\n` +
76
+ `Or create: ${join(USER_DIR, '.env')} with TELEGRAM_BOT_TOKEN=<token>`
77
+ )
66
78
  }
67
79
 
68
80
  if (config.availableAgents.length === 0) {