claude-remote-cli 3.11.1 → 3.11.2

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.
@@ -346,6 +346,8 @@ async function main() {
346
346
  args: [...resolved.claudeArgs, ...(resolved.yolo ? AGENT_YOLO_ARGS[resolved.agent] : [])],
347
347
  configPath: CONFIG_PATH,
348
348
  useTmux: resolved.useTmux,
349
+ yolo: resolved.yolo,
350
+ claudeArgs: resolved.claudeArgs,
349
351
  ...(opts.initialPrompt != null && { initialPrompt: opts.initialPrompt }),
350
352
  });
351
353
  },
@@ -891,6 +893,8 @@ async function main() {
891
893
  displayName: sessions.nextAgentName(),
892
894
  args: baseArgs,
893
895
  useTmux: resolved.useTmux,
896
+ yolo: resolved.yolo,
897
+ claudeArgs: resolved.claudeArgs,
894
898
  ...(safeCols != null && { cols: safeCols }),
895
899
  ...(safeRows != null && { rows: safeRows }),
896
900
  ...(initialPrompt != null && { initialPrompt }),
@@ -923,6 +927,8 @@ async function main() {
923
927
  args,
924
928
  configPath: CONFIG_PATH,
925
929
  useTmux: resolved.useTmux,
930
+ yolo: resolved.yolo,
931
+ claudeArgs: resolved.claudeArgs,
926
932
  ...(safeCols != null && { cols: safeCols }),
927
933
  ...(safeRows != null && { rows: safeRows }),
928
934
  ...(initialPrompt != null && { initialPrompt }),
@@ -974,6 +980,8 @@ async function main() {
974
980
  args,
975
981
  configPath: CONFIG_PATH,
976
982
  useTmux: resolved.useTmux,
983
+ yolo: resolved.yolo,
984
+ claudeArgs: resolved.claudeArgs,
977
985
  ...(safeCols != null && { cols: safeCols }),
978
986
  ...(safeRows != null && { rows: safeRows }),
979
987
  needsBranchRename: isMountainName || (needsBranchRename ?? false),
@@ -1035,6 +1043,8 @@ async function main() {
1035
1043
  args,
1036
1044
  branchName,
1037
1045
  useTmux: resolved.useTmux,
1046
+ yolo: resolved.yolo,
1047
+ claudeArgs: resolved.claudeArgs,
1038
1048
  ...(safeCols != null && { cols: safeCols }),
1039
1049
  ...(safeRows != null && { rows: safeRows }),
1040
1050
  });
@@ -48,7 +48,7 @@ function writeHooksSettingsFile(sessionId, port, token) {
48
48
  return filePath;
49
49
  }
50
50
  export function createPtySession(params, sessionsMap, idleChangeCallbacks, stateChangeCallbacks = [], sessionEndCallbacks = []) {
51
- const { id, type, agent = 'claude', repoName, repoPath, cwd, root, worktreeName, branchName, displayName, command, args: rawArgs = [], cols = 80, rows = 24, configPath, useTmux: paramUseTmux, tmuxSessionName: paramTmuxSessionName, initialScrollback, restored: paramRestored, port, forceOutputParser, } = params;
51
+ const { id, type, agent = 'claude', repoName, repoPath, cwd, root, worktreeName, branchName, displayName, command, args: rawArgs = [], cols = 80, rows = 24, configPath, useTmux: paramUseTmux, tmuxSessionName: paramTmuxSessionName, initialScrollback, restored: paramRestored, port, forceOutputParser, yolo: paramYolo, claudeArgs: paramClaudeArgs, } = params;
52
52
  let args = rawArgs;
53
53
  const createdAt = new Date().toISOString();
54
54
  const resolvedCommand = command || AGENT_COMMANDS[agent];
@@ -121,6 +121,8 @@ export function createPtySession(params, sessionsMap, idleChangeCallbacks, state
121
121
  hookToken,
122
122
  hooksActive,
123
123
  cleanedUp: false,
124
+ yolo: paramYolo ?? false,
125
+ claudeArgs: paramClaudeArgs ?? [],
124
126
  _lastHookTime: undefined,
125
127
  };
126
128
  sessionsMap.set(id, session);
@@ -242,10 +242,12 @@ function serializeAll(configDir) {
242
242
  tmuxSessionName: session.tmuxSessionName,
243
243
  customCommand: session.customCommand,
244
244
  cwd: session.cwd,
245
+ yolo: session.yolo,
246
+ claudeArgs: session.claudeArgs,
245
247
  });
246
248
  }
247
249
  const pending = {
248
- version: 1,
250
+ version: 2,
249
251
  timestamp: new Date().toISOString(),
250
252
  sessions: serializedPty,
251
253
  };
@@ -306,13 +308,23 @@ async function restoreFromDisk(configDir) {
306
308
  args = ['-u', 'attach-session', '-t', s.tmuxSessionName];
307
309
  }
308
310
  else {
309
- // Tmux session died — fall back to agent with continue args
310
- args = [...AGENT_CONTINUE_ARGS[s.agent]];
311
+ // Tmux session died — fall back to agent with continue args + preserved flags
312
+ // Continue args first: Codex uses subcommands (resume --last) that must precede flags
313
+ args = [
314
+ ...AGENT_CONTINUE_ARGS[s.agent],
315
+ ...(s.claudeArgs ?? []),
316
+ ...(s.yolo ? AGENT_YOLO_ARGS[s.agent] : []),
317
+ ];
311
318
  }
312
319
  }
313
320
  else {
314
- // Non-tmux agent session — respawn with continue args
315
- args = [...AGENT_CONTINUE_ARGS[s.agent]];
321
+ // Non-tmux agent session — respawn with continue args + preserved flags
322
+ // Continue args first: Codex uses subcommands (resume --last) that must precede flags
323
+ args = [
324
+ ...AGENT_CONTINUE_ARGS[s.agent],
325
+ ...(s.claudeArgs ?? []),
326
+ ...(s.yolo ? AGENT_YOLO_ARGS[s.agent] : []),
327
+ ];
316
328
  }
317
329
  try {
318
330
  const createParams = {
@@ -330,6 +342,8 @@ async function restoreFromDisk(configDir) {
330
342
  useTmux: false, // Don't re-wrap in tmux — either attaching to existing or using plain agent
331
343
  tmuxSessionName: s.tmuxSessionName,
332
344
  restored: true,
345
+ yolo: s.yolo ?? false,
346
+ claudeArgs: s.claudeArgs ?? [],
333
347
  };
334
348
  if (command)
335
349
  createParams.command = command;
@@ -507,7 +507,7 @@ describe('session persistence', () => {
507
507
  const pendingPath = path.join(configDir, 'pending-sessions.json');
508
508
  assert.ok(fs.existsSync(pendingPath), 'pending-sessions.json should exist');
509
509
  const pending = JSON.parse(fs.readFileSync(pendingPath, 'utf-8'));
510
- assert.strictEqual(pending.version, 1);
510
+ assert.strictEqual(pending.version, 2);
511
511
  assert.ok(pending.timestamp);
512
512
  assert.strictEqual(pending.sessions.length, 1);
513
513
  assert.strictEqual(pending.sessions[0].id, s.id);
@@ -724,6 +724,80 @@ describe('session persistence', () => {
724
724
  assert.strictEqual(restoredTmux.tmuxSessionName, 'crc-tmux-session-tmux-rou');
725
725
  assert.strictEqual(restoredTmux.displayName, 'Tmux Session');
726
726
  });
727
+ it('serialize/restore preserves yolo flag', async () => {
728
+ const configDir = createTmpDir();
729
+ const s = sessions.create({
730
+ repoName: 'test-repo',
731
+ repoPath: '/tmp',
732
+ command: '/bin/cat',
733
+ args: [],
734
+ yolo: true,
735
+ });
736
+ const session = sessions.get(s.id);
737
+ assert.ok(session);
738
+ assert.strictEqual(session.yolo, true);
739
+ serializeAll(configDir);
740
+ sessions.kill(s.id);
741
+ // Verify yolo is in the serialized JSON
742
+ const pending = JSON.parse(fs.readFileSync(path.join(configDir, 'pending-sessions.json'), 'utf-8'));
743
+ assert.strictEqual(pending.version, 2);
744
+ assert.strictEqual(pending.sessions[0].yolo, true);
745
+ await restoreFromDisk(configDir);
746
+ const restored = sessions.get(s.id);
747
+ assert.ok(restored);
748
+ assert.strictEqual(restored.yolo, true);
749
+ });
750
+ it('serialize/restore preserves claudeArgs', async () => {
751
+ const configDir = createTmpDir();
752
+ const s = sessions.create({
753
+ repoName: 'test-repo',
754
+ repoPath: '/tmp',
755
+ command: '/bin/cat',
756
+ args: [],
757
+ claudeArgs: ['--model', 'opus', '--verbose'],
758
+ });
759
+ const session = sessions.get(s.id);
760
+ assert.ok(session);
761
+ assert.deepStrictEqual(session.claudeArgs, ['--model', 'opus', '--verbose']);
762
+ serializeAll(configDir);
763
+ sessions.kill(s.id);
764
+ await restoreFromDisk(configDir);
765
+ const restored = sessions.get(s.id);
766
+ assert.ok(restored);
767
+ assert.deepStrictEqual(restored.claudeArgs, ['--model', 'opus', '--verbose']);
768
+ });
769
+ it('restoreFromDisk handles v1 pending files without yolo/claudeArgs', async () => {
770
+ const configDir = createTmpDir();
771
+ // Write a v1 pending file (no yolo/claudeArgs fields)
772
+ const pending = {
773
+ version: 1,
774
+ timestamp: new Date().toISOString(),
775
+ sessions: [{
776
+ id: 'v1-compat-test',
777
+ type: 'worktree',
778
+ agent: 'claude',
779
+ root: '',
780
+ repoName: 'test-repo',
781
+ repoPath: '/tmp',
782
+ worktreeName: 'my-wt',
783
+ branchName: 'my-branch',
784
+ displayName: 'v1-session',
785
+ createdAt: new Date().toISOString(),
786
+ lastActivity: new Date().toISOString(),
787
+ useTmux: false,
788
+ tmuxSessionName: '',
789
+ customCommand: '/bin/cat',
790
+ cwd: '/tmp',
791
+ }],
792
+ };
793
+ fs.writeFileSync(path.join(configDir, 'pending-sessions.json'), JSON.stringify(pending));
794
+ const restored = await restoreFromDisk(configDir);
795
+ assert.strictEqual(restored, 1);
796
+ const session = sessions.get('v1-compat-test');
797
+ assert.ok(session);
798
+ assert.strictEqual(session.yolo, false);
799
+ assert.deepStrictEqual(session.claudeArgs, []);
800
+ });
727
801
  it('serializeAll captures session state before kill', () => {
728
802
  const configDir = createTmpDir();
729
803
  const s = sessions.create({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-remote-cli",
3
- "version": "3.11.1",
3
+ "version": "3.11.2",
4
4
  "description": "Remote web interface for Claude Code CLI sessions",
5
5
  "type": "module",
6
6
  "main": "dist/server/index.js",