forkoff 1.1.0 → 1.1.1

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/dist/index.js CHANGED
@@ -454,6 +454,7 @@ function createProgram() {
454
454
  const spinner = (0, logger_1.createSpinner)('Initializing...').start();
455
455
  try {
456
456
  tools_1.PermissionIpcManager.cleanupStaleTempFiles();
457
+ tools_1.claudeProcessManager.cleanupAllPermissionState();
457
458
  spinner.succeed('Ready!\n');
458
459
  // Detect connected tools
459
460
  spinner.start('Detecting AI coding tools...');
@@ -1097,6 +1098,13 @@ function createProgram() {
1097
1098
  websocket_1.wsClient.on('disconnected', (reason) => {
1098
1099
  console.log(chalk_1.default.yellow(`\nMobile disconnected: ${reason}`));
1099
1100
  console.log(chalk_1.default.dim('Waiting for mobile to reconnect...'));
1101
+ tools_1.claudeProcessManager.autoAllowAllPendingPrompts();
1102
+ tools_1.claudeProcessManager.cleanupAllPermissionState();
1103
+ tools_1.claudeProcessManager.clearAllTakenOver();
1104
+ });
1105
+ websocket_1.wsClient.on('session_release', (data) => {
1106
+ console.log(chalk_1.default.dim(`[Session] Mobile released session: ${data.sessionKey}`));
1107
+ tools_1.claudeProcessManager.releaseSession(data.sessionKey);
1100
1108
  });
1101
1109
  websocket_1.wsClient.on('error', (error) => {
1102
1110
  console.error(chalk_1.default.red(`Connection error: ${error.message}`));
@@ -241,6 +241,11 @@ declare class ClaudeProcessManager extends EventEmitter {
241
241
  * Clear all taken-over sessions (e.g., when mobile disconnects).
242
242
  */
243
243
  clearAllTakenOver(): void;
244
+ /**
245
+ * Release a single session — clean up its hooks and IPC.
246
+ * Called when mobile navigates away from the session screen after taking over.
247
+ */
248
+ releaseSession(sessionKey: string): void;
244
249
  /**
245
250
  * Get all pending permission prompts across all IPC managers.
246
251
  * Used to sync pending permissions to mobile on take-over.
@@ -822,6 +822,50 @@ class ClaudeProcessManager extends events_1.EventEmitter {
822
822
  this.takenOverSessions.clear();
823
823
  console.log(`[Claude Process] All taken-over sessions cleared`);
824
824
  }
825
+ /**
826
+ * Release a single session — clean up its hooks and IPC.
827
+ * Called when mobile navigates away from the session screen after taking over.
828
+ */
829
+ releaseSession(sessionKey) {
830
+ // Find the process by sessionKey or terminalSessionId
831
+ let terminalSessionId;
832
+ let directory;
833
+ for (const [id, info] of this.processes) {
834
+ if (id === sessionKey || info.sessionKey === sessionKey) {
835
+ terminalSessionId = id;
836
+ directory = info.directory;
837
+ break;
838
+ }
839
+ }
840
+ // Also check closed sessions in case the process already exited
841
+ if (!terminalSessionId) {
842
+ for (const [id, info] of this.closedSessions) {
843
+ if (id === sessionKey || info.sessionKey === sessionKey) {
844
+ terminalSessionId = id;
845
+ directory = info.directory;
846
+ break;
847
+ }
848
+ }
849
+ }
850
+ if (terminalSessionId) {
851
+ // Stop permission IPC for this session
852
+ this.stopPermissionIpc(terminalSessionId);
853
+ // Remove hook from directory if no other active sessions use it
854
+ if (directory) {
855
+ const otherSessionsInDir = Array.from(this.processes.values())
856
+ .filter(p => p.directory === directory && p.terminalSessionId !== terminalSessionId);
857
+ if (otherSessionsInDir.length === 0) {
858
+ this.removeHook(directory);
859
+ }
860
+ }
861
+ // Clear taken-over state
862
+ this.takenOverSessions.delete(terminalSessionId);
863
+ console.log(`[Claude Process] Session released: ${terminalSessionId}`);
864
+ }
865
+ else {
866
+ console.log(`[Claude Process] Session release: no matching session found for ${sessionKey}`);
867
+ }
868
+ }
825
869
  /**
826
870
  * Get all pending permission prompts across all IPC managers.
827
871
  * Used to sync pending permissions to mobile on take-over.
package/dist/websocket.js CHANGED
@@ -89,7 +89,7 @@ const PLAINTEXT_DROP_EVENTS = [
89
89
  'directory_list', 'transcript_fetch', 'transcript_subscribe',
90
90
  'read_file', 'claude_approval_response', 'permission_response',
91
91
  'permission_rules_sync', 'claude_abort', 'tab_complete',
92
- 'usage_stats_request', 'sdk_session_history',
92
+ 'usage_stats_request', 'sdk_session_history', 'session_release',
93
93
  ];
94
94
  /** Events forwarded from server that do NOT need plaintext-drop checking */
95
95
  const PASSTHROUGH_EVENTS = [
package/eas.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "cli": {
3
+ "version": ">= 16.26.0",
4
+ "appVersionSource": "remote"
5
+ },
6
+ "build": {
7
+ "development": {
8
+ "developmentClient": true,
9
+ "distribution": "internal"
10
+ },
11
+ "preview": {
12
+ "distribution": "internal"
13
+ },
14
+ "production": {
15
+ "autoIncrement": true
16
+ }
17
+ },
18
+ "submit": {
19
+ "production": {}
20
+ }
21
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forkoff",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "CLI tool to connect your AI coding tools to mobile | Open Beta - Download the app: https://testflight.apple.com/join/dhh5FrN7",
5
5
  "main": "dist/integration.js",
6
6
  "types": "dist/integration.d.ts",