cc2im 0.2.2 → 0.2.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.
package/README.md CHANGED
@@ -117,6 +117,14 @@ cc2im 为**单用户场景**设计(一个人通过微信控制自己的多个
117
117
 
118
118
  ## 更新日志
119
119
 
120
+ ### v0.2.4 (2026-04-21)
121
+
122
+ - **fix**: 新注册的 agent 没有历史 session 时,`claude --continue` 立即 exit 1,之前会连续 5 次重启失败被标记阵亡;现在检测到快速非零退出会在下次重启时自动跳过 `--continue` 用新会话启动
123
+
124
+ ### v0.2.3 (2026-04-20)
125
+
126
+ - **feat**: 启动 CC 实例时默认注入 `--permission-mode auto --allowedTools '*' --effort max`,让 agent 在微信场景下自主执行不卡权限审批。per-agent `claudeArgs`(`~/.cc2im/agents.json`)仍可按 flag 名覆盖
127
+
120
128
  ### v0.2.2 (2026-04-20)
121
129
 
122
130
  - **fix**: CC 启动时若 `--continue` 触发 "Resume from summary" 会话选择器,expect 脚本现在会自动选第一项;新增 60s 连接超时兜底,卡住时自动 kill 并用新会话重试
package/dist/cli.js CHANGED
@@ -20,6 +20,7 @@ import { spawn } from 'node:child_process';
20
20
  import qrterm from 'qrcode-terminal';
21
21
  import { SOCKET_DIR, ensureSocketDir } from './shared/socket.js';
22
22
  import { ensureMcpJson } from './shared/mcp-config.js';
23
+ import { DEFAULT_CLAUDE_ARGS, mergeClaudeArgs } from './shared/claude-args.js';
23
24
  const AGENTS_JSON_PATH = join(SOCKET_DIR, 'agents.json');
24
25
  const BASE_URL = 'https://ilinkai.weixin.qq.com';
25
26
  const BANNER = [
@@ -142,7 +143,7 @@ function startAgentForeground(name) {
142
143
  ensureMcpJson(agent.cwd, spokeScript, name);
143
144
  const claudeArgs = [
144
145
  '--dangerously-load-development-channels', 'server:cc2im',
145
- ...(agent.claudeArgs || []),
146
+ ...mergeClaudeArgs(DEFAULT_CLAUDE_ARGS, agent.claudeArgs || []),
146
147
  ];
147
148
  const cmd = process.platform === 'darwin' ? 'caffeinate' : 'claude';
148
149
  const args = process.platform === 'darwin' ? ['-i', 'claude', ...claudeArgs] : claudeArgs;
@@ -7,6 +7,7 @@ import { join } from 'node:path';
7
7
  import { spawn } from 'node:child_process';
8
8
  import { SOCKET_DIR } from '../shared/socket.js';
9
9
  import { ensureMcpJson } from '../shared/mcp-config.js';
10
+ import { DEFAULT_CLAUDE_ARGS, mergeClaudeArgs } from '../shared/claude-args.js';
10
11
  const AGENTS_JSON_PATH = join(SOCKET_DIR, 'agents.json');
11
12
  const PGID_FILE_PATH = join(SOCKET_DIR, 'agent-pgids.json');
12
13
  const STOP_TIMEOUT_MS = 5000;
@@ -158,7 +159,7 @@ export class AgentManager {
158
159
  const claudeArgs = [
159
160
  '--dangerously-load-development-channels', 'server:cc2im',
160
161
  ...(skipContinue ? [] : ['--continue']), // resume most recent session unless last attempt stalled
161
- ...(agent.claudeArgs || []),
162
+ ...mergeClaudeArgs(DEFAULT_CLAUDE_ARGS, agent.claudeArgs || []), // permission-mode/allowedTools/effort defaults + per-agent override
162
163
  ];
163
164
  // Use `expect` to allocate a pseudo-tty so CC enters interactive mode.
164
165
  // Unlike `script`, `expect` creates its own pty without needing a tty stdin.
@@ -219,6 +220,7 @@ export class AgentManager {
219
220
  }, CONNECT_TIMEOUT_MS);
220
221
  child.on('exit', (code) => {
221
222
  clearTimeout(connectTimer);
223
+ const wasConnected = this.getConnectedAgents().includes(name);
222
224
  console.log(`[agent-manager] Agent "${name}" exited (code ${code})`);
223
225
  this.processes.delete(name);
224
226
  this.savePgids();
@@ -234,6 +236,12 @@ export class AgentManager {
234
236
  const agentConfig = this.config.agents[name];
235
237
  if (!agentConfig?.autoStart)
236
238
  return;
239
+ // If CC exited fast with non-zero code before ever connecting, --continue probably failed
240
+ // (no prior session for a new agent). Skip --continue on next restart to start fresh.
241
+ if (!wasConnected && code !== 0 && code !== null && !skipContinue) {
242
+ console.log(`[agent-manager] "${name}" exited before connecting — will skip --continue on next restart`);
243
+ this.skipContinueOnce.add(name);
244
+ }
237
245
  // Backoff: track consecutive restarts within time window
238
246
  const now = Date.now();
239
247
  const attempts = this.restartAttempts.get(name);
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Default CC CLI args injected on every spawn.
3
+ * Per-agent claudeArgs (in agents.json) override these by flag name.
4
+ */
5
+ export declare const DEFAULT_CLAUDE_ARGS: readonly string[];
6
+ /**
7
+ * Merge defaults with per-agent overrides. If a flag name appears in `userArgs`,
8
+ * its default (flag + value) is dropped so the user's value wins.
9
+ */
10
+ export declare function mergeClaudeArgs(defaults: readonly string[], userArgs: readonly string[]): string[];
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Default CC CLI args injected on every spawn.
3
+ * Per-agent claudeArgs (in agents.json) override these by flag name.
4
+ */
5
+ export const DEFAULT_CLAUDE_ARGS = [
6
+ '--permission-mode', 'auto',
7
+ '--allowedTools', '*',
8
+ '--effort', 'max',
9
+ ];
10
+ /**
11
+ * Merge defaults with per-agent overrides. If a flag name appears in `userArgs`,
12
+ * its default (flag + value) is dropped so the user's value wins.
13
+ */
14
+ export function mergeClaudeArgs(defaults, userArgs) {
15
+ const userFlags = new Set(userArgs.filter(t => t.startsWith('--')));
16
+ const filtered = [];
17
+ for (let i = 0; i < defaults.length; i++) {
18
+ const token = defaults[i];
19
+ if (token.startsWith('--') && userFlags.has(token)) {
20
+ if (i + 1 < defaults.length && !defaults[i + 1].startsWith('--'))
21
+ i++;
22
+ continue;
23
+ }
24
+ filtered.push(token);
25
+ }
26
+ return [...filtered, ...userArgs];
27
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cc2im",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "IM gateway for multiple local Claude Code instances",
5
5
  "author": "roxorlt",
6
6
  "license": "MIT",