happy-coder 0.11.2-0 → 0.12.0-0

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.cjs CHANGED
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  require('chalk');
4
- require('./index-CFWfkM2k.cjs');
5
- require('./types-D6ZewYb6.cjs');
4
+ require('./index-BCQGaH21.cjs');
5
+ require('./types-C7skJO9Y.cjs');
6
6
  require('zod');
7
7
  require('node:child_process');
8
8
  require('node:os');
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import 'chalk';
2
- import './index-B6KoidwE.mjs';
3
- import './types-CVOFMcT8.mjs';
2
+ import './index-BWDbDDaX.mjs';
3
+ import './types-DdwJ6K-A.mjs';
4
4
  import 'zod';
5
5
  import 'node:child_process';
6
6
  import 'node:os';
package/dist/lib.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var types = require('./types-D6ZewYb6.cjs');
3
+ var types = require('./types-C7skJO9Y.cjs');
4
4
  require('axios');
5
5
  require('chalk');
6
6
  require('fs');
package/dist/lib.d.cts CHANGED
@@ -66,7 +66,7 @@ declare const RawJSONLinesSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
66
66
  }, z.ZodTypeAny, "passthrough">>, z.ZodObject<{
67
67
  uuid: z.ZodString;
68
68
  type: z.ZodLiteral<"assistant">;
69
- message: z.ZodObject<{
69
+ message: z.ZodOptional<z.ZodObject<{
70
70
  usage: z.ZodOptional<z.ZodObject<{
71
71
  input_tokens: z.ZodNumber;
72
72
  cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
@@ -86,7 +86,6 @@ declare const RawJSONLinesSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
86
86
  output_tokens: z.ZodNumber;
87
87
  service_tier: z.ZodOptional<z.ZodString>;
88
88
  }, z.ZodTypeAny, "passthrough">>>;
89
- content: z.ZodAny;
90
89
  }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
91
90
  usage: z.ZodOptional<z.ZodObject<{
92
91
  input_tokens: z.ZodNumber;
@@ -107,7 +106,6 @@ declare const RawJSONLinesSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
107
106
  output_tokens: z.ZodNumber;
108
107
  service_tier: z.ZodOptional<z.ZodString>;
109
108
  }, z.ZodTypeAny, "passthrough">>>;
110
- content: z.ZodAny;
111
109
  }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
112
110
  usage: z.ZodOptional<z.ZodObject<{
113
111
  input_tokens: z.ZodNumber;
@@ -128,12 +126,11 @@ declare const RawJSONLinesSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
128
126
  output_tokens: z.ZodNumber;
129
127
  service_tier: z.ZodOptional<z.ZodString>;
130
128
  }, z.ZodTypeAny, "passthrough">>>;
131
- content: z.ZodAny;
132
- }, z.ZodTypeAny, "passthrough">>;
129
+ }, z.ZodTypeAny, "passthrough">>>;
133
130
  }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
134
131
  uuid: z.ZodString;
135
132
  type: z.ZodLiteral<"assistant">;
136
- message: z.ZodObject<{
133
+ message: z.ZodOptional<z.ZodObject<{
137
134
  usage: z.ZodOptional<z.ZodObject<{
138
135
  input_tokens: z.ZodNumber;
139
136
  cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
@@ -153,7 +150,6 @@ declare const RawJSONLinesSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
153
150
  output_tokens: z.ZodNumber;
154
151
  service_tier: z.ZodOptional<z.ZodString>;
155
152
  }, z.ZodTypeAny, "passthrough">>>;
156
- content: z.ZodAny;
157
153
  }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
158
154
  usage: z.ZodOptional<z.ZodObject<{
159
155
  input_tokens: z.ZodNumber;
@@ -174,7 +170,6 @@ declare const RawJSONLinesSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
174
170
  output_tokens: z.ZodNumber;
175
171
  service_tier: z.ZodOptional<z.ZodString>;
176
172
  }, z.ZodTypeAny, "passthrough">>>;
177
- content: z.ZodAny;
178
173
  }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
179
174
  usage: z.ZodOptional<z.ZodObject<{
180
175
  input_tokens: z.ZodNumber;
@@ -195,12 +190,11 @@ declare const RawJSONLinesSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
195
190
  output_tokens: z.ZodNumber;
196
191
  service_tier: z.ZodOptional<z.ZodString>;
197
192
  }, z.ZodTypeAny, "passthrough">>>;
198
- content: z.ZodAny;
199
- }, z.ZodTypeAny, "passthrough">>;
193
+ }, z.ZodTypeAny, "passthrough">>>;
200
194
  }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
201
195
  uuid: z.ZodString;
202
196
  type: z.ZodLiteral<"assistant">;
203
- message: z.ZodObject<{
197
+ message: z.ZodOptional<z.ZodObject<{
204
198
  usage: z.ZodOptional<z.ZodObject<{
205
199
  input_tokens: z.ZodNumber;
206
200
  cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
@@ -220,7 +214,6 @@ declare const RawJSONLinesSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
220
214
  output_tokens: z.ZodNumber;
221
215
  service_tier: z.ZodOptional<z.ZodString>;
222
216
  }, z.ZodTypeAny, "passthrough">>>;
223
- content: z.ZodAny;
224
217
  }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
225
218
  usage: z.ZodOptional<z.ZodObject<{
226
219
  input_tokens: z.ZodNumber;
@@ -241,7 +234,6 @@ declare const RawJSONLinesSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
241
234
  output_tokens: z.ZodNumber;
242
235
  service_tier: z.ZodOptional<z.ZodString>;
243
236
  }, z.ZodTypeAny, "passthrough">>>;
244
- content: z.ZodAny;
245
237
  }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
246
238
  usage: z.ZodOptional<z.ZodObject<{
247
239
  input_tokens: z.ZodNumber;
@@ -262,8 +254,7 @@ declare const RawJSONLinesSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
262
254
  output_tokens: z.ZodNumber;
263
255
  service_tier: z.ZodOptional<z.ZodString>;
264
256
  }, z.ZodTypeAny, "passthrough">>>;
265
- content: z.ZodAny;
266
- }, z.ZodTypeAny, "passthrough">>;
257
+ }, z.ZodTypeAny, "passthrough">>>;
267
258
  }, z.ZodTypeAny, "passthrough">>, z.ZodObject<{
268
259
  type: z.ZodLiteral<"summary">;
269
260
  summary: z.ZodString;
package/dist/lib.d.mts CHANGED
@@ -66,7 +66,7 @@ declare const RawJSONLinesSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
66
66
  }, z.ZodTypeAny, "passthrough">>, z.ZodObject<{
67
67
  uuid: z.ZodString;
68
68
  type: z.ZodLiteral<"assistant">;
69
- message: z.ZodObject<{
69
+ message: z.ZodOptional<z.ZodObject<{
70
70
  usage: z.ZodOptional<z.ZodObject<{
71
71
  input_tokens: z.ZodNumber;
72
72
  cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
@@ -86,7 +86,6 @@ declare const RawJSONLinesSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
86
86
  output_tokens: z.ZodNumber;
87
87
  service_tier: z.ZodOptional<z.ZodString>;
88
88
  }, z.ZodTypeAny, "passthrough">>>;
89
- content: z.ZodAny;
90
89
  }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
91
90
  usage: z.ZodOptional<z.ZodObject<{
92
91
  input_tokens: z.ZodNumber;
@@ -107,7 +106,6 @@ declare const RawJSONLinesSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
107
106
  output_tokens: z.ZodNumber;
108
107
  service_tier: z.ZodOptional<z.ZodString>;
109
108
  }, z.ZodTypeAny, "passthrough">>>;
110
- content: z.ZodAny;
111
109
  }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
112
110
  usage: z.ZodOptional<z.ZodObject<{
113
111
  input_tokens: z.ZodNumber;
@@ -128,12 +126,11 @@ declare const RawJSONLinesSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
128
126
  output_tokens: z.ZodNumber;
129
127
  service_tier: z.ZodOptional<z.ZodString>;
130
128
  }, z.ZodTypeAny, "passthrough">>>;
131
- content: z.ZodAny;
132
- }, z.ZodTypeAny, "passthrough">>;
129
+ }, z.ZodTypeAny, "passthrough">>>;
133
130
  }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
134
131
  uuid: z.ZodString;
135
132
  type: z.ZodLiteral<"assistant">;
136
- message: z.ZodObject<{
133
+ message: z.ZodOptional<z.ZodObject<{
137
134
  usage: z.ZodOptional<z.ZodObject<{
138
135
  input_tokens: z.ZodNumber;
139
136
  cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
@@ -153,7 +150,6 @@ declare const RawJSONLinesSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
153
150
  output_tokens: z.ZodNumber;
154
151
  service_tier: z.ZodOptional<z.ZodString>;
155
152
  }, z.ZodTypeAny, "passthrough">>>;
156
- content: z.ZodAny;
157
153
  }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
158
154
  usage: z.ZodOptional<z.ZodObject<{
159
155
  input_tokens: z.ZodNumber;
@@ -174,7 +170,6 @@ declare const RawJSONLinesSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
174
170
  output_tokens: z.ZodNumber;
175
171
  service_tier: z.ZodOptional<z.ZodString>;
176
172
  }, z.ZodTypeAny, "passthrough">>>;
177
- content: z.ZodAny;
178
173
  }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
179
174
  usage: z.ZodOptional<z.ZodObject<{
180
175
  input_tokens: z.ZodNumber;
@@ -195,12 +190,11 @@ declare const RawJSONLinesSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
195
190
  output_tokens: z.ZodNumber;
196
191
  service_tier: z.ZodOptional<z.ZodString>;
197
192
  }, z.ZodTypeAny, "passthrough">>>;
198
- content: z.ZodAny;
199
- }, z.ZodTypeAny, "passthrough">>;
193
+ }, z.ZodTypeAny, "passthrough">>>;
200
194
  }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
201
195
  uuid: z.ZodString;
202
196
  type: z.ZodLiteral<"assistant">;
203
- message: z.ZodObject<{
197
+ message: z.ZodOptional<z.ZodObject<{
204
198
  usage: z.ZodOptional<z.ZodObject<{
205
199
  input_tokens: z.ZodNumber;
206
200
  cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
@@ -220,7 +214,6 @@ declare const RawJSONLinesSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
220
214
  output_tokens: z.ZodNumber;
221
215
  service_tier: z.ZodOptional<z.ZodString>;
222
216
  }, z.ZodTypeAny, "passthrough">>>;
223
- content: z.ZodAny;
224
217
  }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
225
218
  usage: z.ZodOptional<z.ZodObject<{
226
219
  input_tokens: z.ZodNumber;
@@ -241,7 +234,6 @@ declare const RawJSONLinesSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
241
234
  output_tokens: z.ZodNumber;
242
235
  service_tier: z.ZodOptional<z.ZodString>;
243
236
  }, z.ZodTypeAny, "passthrough">>>;
244
- content: z.ZodAny;
245
237
  }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
246
238
  usage: z.ZodOptional<z.ZodObject<{
247
239
  input_tokens: z.ZodNumber;
@@ -262,8 +254,7 @@ declare const RawJSONLinesSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
262
254
  output_tokens: z.ZodNumber;
263
255
  service_tier: z.ZodOptional<z.ZodString>;
264
256
  }, z.ZodTypeAny, "passthrough">>>;
265
- content: z.ZodAny;
266
- }, z.ZodTypeAny, "passthrough">>;
257
+ }, z.ZodTypeAny, "passthrough">>>;
267
258
  }, z.ZodTypeAny, "passthrough">>, z.ZodObject<{
268
259
  type: z.ZodLiteral<"summary">;
269
260
  summary: z.ZodString;
package/dist/lib.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-CVOFMcT8.mjs';
1
+ export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-DdwJ6K-A.mjs';
2
2
  import 'axios';
3
3
  import 'chalk';
4
4
  import 'fs';
@@ -2,14 +2,14 @@
2
2
 
3
3
  var ink = require('ink');
4
4
  var React = require('react');
5
- var types = require('./types-D6ZewYb6.cjs');
5
+ var types = require('./types-C7skJO9Y.cjs');
6
6
  var index_js = require('@modelcontextprotocol/sdk/client/index.js');
7
7
  var stdio_js = require('@modelcontextprotocol/sdk/client/stdio.js');
8
8
  var z = require('zod');
9
9
  var types_js = require('@modelcontextprotocol/sdk/types.js');
10
10
  var child_process = require('child_process');
11
11
  var node_crypto = require('node:crypto');
12
- var index = require('./index-CFWfkM2k.cjs');
12
+ var index = require('./index-BCQGaH21.cjs');
13
13
  var os = require('node:os');
14
14
  var node_path = require('node:path');
15
15
  var fs = require('node:fs');
@@ -75,7 +75,7 @@ class CodexMcpClient {
75
75
  constructor() {
76
76
  this.client = new index_js.Client(
77
77
  { name: "happy-codex-client", version: "1.0.0" },
78
- { capabilities: { tools: {}, elicitation: {} } }
78
+ { capabilities: { elicitation: {} } }
79
79
  );
80
80
  this.client.setNotificationHandler(z.z.object({
81
81
  method: z.z.literal("codex/event"),
@@ -1,13 +1,13 @@
1
1
  import { useStdout, useInput, Box, Text, render } from 'ink';
2
2
  import React, { useState, useRef, useEffect, useCallback } from 'react';
3
- import { l as logger, A as ApiClient, r as readSettings, p as projectPath, c as configuration, b as packageJson } from './types-CVOFMcT8.mjs';
3
+ import { l as logger, A as ApiClient, r as readSettings, p as projectPath, c as configuration, b as packageJson } from './types-DdwJ6K-A.mjs';
4
4
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
5
5
  import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
6
6
  import { z } from 'zod';
7
7
  import { ElicitRequestSchema } from '@modelcontextprotocol/sdk/types.js';
8
8
  import { execSync } from 'child_process';
9
9
  import { randomUUID } from 'node:crypto';
10
- import { i as initialMachineMetadata, n as notifyDaemonSessionStarted, M as MessageQueue2, h as hashObject, r as registerKillSessionHandler, a as MessageBuffer, s as startHappyServer, t as trimIdent, b as stopCaffeinate } from './index-B6KoidwE.mjs';
10
+ import { i as initialMachineMetadata, n as notifyDaemonSessionStarted, M as MessageQueue2, h as hashObject, r as registerKillSessionHandler, a as MessageBuffer, s as startHappyServer, t as trimIdent, b as stopCaffeinate } from './index-BWDbDDaX.mjs';
11
11
  import os from 'node:os';
12
12
  import { resolve, join } from 'node:path';
13
13
  import fs from 'node:fs';
@@ -73,7 +73,7 @@ class CodexMcpClient {
73
73
  constructor() {
74
74
  this.client = new Client(
75
75
  { name: "happy-codex-client", version: "1.0.0" },
76
- { capabilities: { tools: {}, elicitation: {} } }
76
+ { capabilities: { elicitation: {} } }
77
77
  );
78
78
  this.client.setNotificationHandler(z.object({
79
79
  method: z.literal("codex/event"),
@@ -42,7 +42,7 @@ function _interopNamespaceDefault(e) {
42
42
  var z__namespace = /*#__PURE__*/_interopNamespaceDefault(z);
43
43
 
44
44
  var name = "happy-coder";
45
- var version = "0.11.2-0";
45
+ var version = "0.12.0-0";
46
46
  var description = "Mobile and Web client for Claude Code and Codex";
47
47
  var author = "Kirill Dubovitskiy";
48
48
  var license = "MIT";
@@ -101,7 +101,9 @@ var scripts = {
101
101
  typecheck: "tsc --noEmit",
102
102
  build: "shx rm -rf dist && npx tsc --noEmit && pkgroll",
103
103
  test: "yarn build && tsx --env-file .env.integration-test node_modules/.bin/vitest run",
104
+ "test:win": "yarn build && npx vitest run",
104
105
  start: "yarn build && ./bin/happy.mjs",
106
+ "start:win": "yarn build && node ./bin/happy.mjs",
105
107
  dev: "tsx src/index.ts",
106
108
  "dev:local-server": "yarn build && tsx --env-file .env.dev-local-server src/index.ts",
107
109
  "dev:integration-test-env": "yarn build && tsx --env-file .env.integration-test src/index.ts",
@@ -110,32 +112,30 @@ var scripts = {
110
112
  postinstall: "node scripts/unpack-tools.cjs"
111
113
  };
112
114
  var dependencies = {
113
- "@anthropic-ai/claude-code": "^2.0.13",
114
- "@anthropic-ai/sdk": "0.65.0",
115
- "@modelcontextprotocol/sdk": "^1.15.1",
115
+ "@modelcontextprotocol/sdk": "^1.22.0",
116
116
  "@stablelib/base64": "^2.0.1",
117
117
  "@stablelib/hex": "^2.0.1",
118
118
  "@types/cross-spawn": "^6.0.6",
119
- "@types/http-proxy": "^1.17.16",
119
+ "@types/http-proxy": "^1.17.17",
120
120
  "@types/ps-list": "^6.2.1",
121
121
  "@types/qrcode-terminal": "^0.12.2",
122
- "@types/react": "^19.1.9",
122
+ "@types/react": "^19.2.7",
123
123
  "@types/tmp": "^0.2.6",
124
- axios: "^1.10.0",
125
- chalk: "^5.4.1",
124
+ axios: "^1.13.2",
125
+ chalk: "^5.6.2",
126
126
  "cross-spawn": "^7.0.6",
127
127
  "expo-server-sdk": "^3.15.0",
128
- fastify: "^5.5.0",
128
+ fastify: "^5.6.2",
129
129
  "fastify-type-provider-zod": "4.0.2",
130
130
  "http-proxy": "^1.18.1",
131
131
  "http-proxy-middleware": "^3.0.5",
132
- ink: "^6.1.0",
132
+ ink: "^6.5.1",
133
133
  open: "^10.2.0",
134
134
  "ps-list": "^8.1.1",
135
135
  "qrcode-terminal": "^0.12.0",
136
- react: "^19.1.1",
136
+ react: "^19.2.0",
137
137
  "socket.io-client": "^4.8.1",
138
- tar: "^7.4.3",
138
+ tar: "^7.5.2",
139
139
  tmp: "^0.2.5",
140
140
  tweetnacl: "^1.0.3",
141
141
  zod: "^3.23.8"
@@ -143,15 +143,15 @@ var dependencies = {
143
143
  var devDependencies = {
144
144
  "@eslint/compat": "^1",
145
145
  "@types/node": ">=20",
146
- "cross-env": "^10.0.0",
146
+ "cross-env": "^10.1.0",
147
147
  dotenv: "^16.6.1",
148
148
  eslint: "^9",
149
149
  "eslint-config-prettier": "^10",
150
150
  pkgroll: "^2.14.2",
151
- "release-it": "^19.0.4",
151
+ "release-it": "^19.0.6",
152
152
  shx: "^0.3.3",
153
153
  "ts-node": "^10",
154
- tsx: "^4.20.3",
154
+ tsx: "^4.20.6",
155
155
  typescript: "^5",
156
156
  vitest: "^3.2.4"
157
157
  };
@@ -1019,7 +1019,7 @@ class RpcHandlerManager {
1019
1019
  }
1020
1020
  }
1021
1021
 
1022
- const __dirname$1 = path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-D6ZewYb6.cjs', document.baseURI).href))));
1022
+ const __dirname$1 = path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-C7skJO9Y.cjs', document.baseURI).href))));
1023
1023
  function projectPath() {
1024
1024
  const path$1 = path.resolve(__dirname$1, "..");
1025
1025
  return path$1;
@@ -1091,10 +1091,28 @@ function run(args, options) {
1091
1091
  });
1092
1092
  }
1093
1093
 
1094
+ function validatePath(targetPath, workingDirectory) {
1095
+ const resolvedTarget = path.resolve(workingDirectory, targetPath);
1096
+ const resolvedWorkingDir = path.resolve(workingDirectory);
1097
+ if (!resolvedTarget.startsWith(resolvedWorkingDir + "/") && resolvedTarget !== resolvedWorkingDir) {
1098
+ return {
1099
+ valid: false,
1100
+ error: `Access denied: Path '${targetPath}' is outside the working directory`
1101
+ };
1102
+ }
1103
+ return { valid: true };
1104
+ }
1105
+
1094
1106
  const execAsync = util.promisify(child_process.exec);
1095
- function registerCommonHandlers(rpcHandlerManager) {
1107
+ function registerCommonHandlers(rpcHandlerManager, workingDirectory) {
1096
1108
  rpcHandlerManager.registerHandler("bash", async (data) => {
1097
1109
  logger.debug("Shell command request:", data.command);
1110
+ if (data.cwd) {
1111
+ const validation = validatePath(data.cwd, workingDirectory);
1112
+ if (!validation.valid) {
1113
+ return { success: false, error: validation.error };
1114
+ }
1115
+ }
1098
1116
  try {
1099
1117
  const options = {
1100
1118
  cwd: data.cwd,
@@ -1130,6 +1148,10 @@ function registerCommonHandlers(rpcHandlerManager) {
1130
1148
  });
1131
1149
  rpcHandlerManager.registerHandler("readFile", async (data) => {
1132
1150
  logger.debug("Read file request:", data.path);
1151
+ const validation = validatePath(data.path, workingDirectory);
1152
+ if (!validation.valid) {
1153
+ return { success: false, error: validation.error };
1154
+ }
1133
1155
  try {
1134
1156
  const buffer = await fs$2.readFile(data.path);
1135
1157
  const content = buffer.toString("base64");
@@ -1141,6 +1163,10 @@ function registerCommonHandlers(rpcHandlerManager) {
1141
1163
  });
1142
1164
  rpcHandlerManager.registerHandler("writeFile", async (data) => {
1143
1165
  logger.debug("Write file request:", data.path);
1166
+ const validation = validatePath(data.path, workingDirectory);
1167
+ if (!validation.valid) {
1168
+ return { success: false, error: validation.error };
1169
+ }
1144
1170
  try {
1145
1171
  if (data.expectedHash !== null && data.expectedHash !== void 0) {
1146
1172
  try {
@@ -1187,6 +1213,10 @@ function registerCommonHandlers(rpcHandlerManager) {
1187
1213
  });
1188
1214
  rpcHandlerManager.registerHandler("listDirectory", async (data) => {
1189
1215
  logger.debug("List directory request:", data.path);
1216
+ const validation = validatePath(data.path, workingDirectory);
1217
+ if (!validation.valid) {
1218
+ return { success: false, error: validation.error };
1219
+ }
1190
1220
  try {
1191
1221
  const entries = await fs$2.readdir(data.path, { withFileTypes: true });
1192
1222
  const directoryEntries = await Promise.all(
@@ -1228,6 +1258,10 @@ function registerCommonHandlers(rpcHandlerManager) {
1228
1258
  });
1229
1259
  rpcHandlerManager.registerHandler("getDirectoryTree", async (data) => {
1230
1260
  logger.debug("Get directory tree request:", data.path, "maxDepth:", data.maxDepth);
1261
+ const validation = validatePath(data.path, workingDirectory);
1262
+ if (!validation.valid) {
1263
+ return { success: false, error: validation.error };
1264
+ }
1231
1265
  async function buildTree(path$1, name, currentDepth) {
1232
1266
  try {
1233
1267
  const stats = await fs$2.stat(path$1);
@@ -1284,6 +1318,12 @@ function registerCommonHandlers(rpcHandlerManager) {
1284
1318
  });
1285
1319
  rpcHandlerManager.registerHandler("ripgrep", async (data) => {
1286
1320
  logger.debug("Ripgrep request with args:", data.args, "cwd:", data.cwd);
1321
+ if (data.cwd) {
1322
+ const validation = validatePath(data.cwd, workingDirectory);
1323
+ if (!validation.valid) {
1324
+ return { success: false, error: validation.error };
1325
+ }
1326
+ }
1287
1327
  try {
1288
1328
  const result = await run$1(data.args, { cwd: data.cwd });
1289
1329
  return {
@@ -1302,6 +1342,12 @@ function registerCommonHandlers(rpcHandlerManager) {
1302
1342
  });
1303
1343
  rpcHandlerManager.registerHandler("difftastic", async (data) => {
1304
1344
  logger.debug("Difftastic request with args:", data.args, "cwd:", data.cwd);
1345
+ if (data.cwd) {
1346
+ const validation = validatePath(data.cwd, workingDirectory);
1347
+ if (!validation.valid) {
1348
+ return { success: false, error: validation.error };
1349
+ }
1350
+ }
1305
1351
  try {
1306
1352
  const result = await run(data.args, { cwd: data.cwd });
1307
1353
  return {
@@ -1351,7 +1397,7 @@ class ApiSessionClient extends node_events.EventEmitter {
1351
1397
  encryptionVariant: this.encryptionVariant,
1352
1398
  logger: (msg, data) => logger.debug(msg, data)
1353
1399
  });
1354
- registerCommonHandlers(this.rpcHandlerManager);
1400
+ registerCommonHandlers(this.rpcHandlerManager, this.metadata.path);
1355
1401
  this.socket = socket_ioClient.io(configuration.serverUrl, {
1356
1402
  auth: {
1357
1403
  token: this.token,
@@ -1467,7 +1513,7 @@ class ApiSessionClient extends node_events.EventEmitter {
1467
1513
  sid: this.sessionId,
1468
1514
  message: encrypted
1469
1515
  });
1470
- if (body.type === "assistant" && body.message.usage) {
1516
+ if (body.type === "assistant" && body.message?.usage) {
1471
1517
  try {
1472
1518
  this.sendUsageData(body.message.usage);
1473
1519
  } catch (error) {
@@ -1641,7 +1687,7 @@ class ApiMachineClient {
1641
1687
  encryptionVariant: this.machine.encryptionVariant,
1642
1688
  logger: (msg, data) => logger.debug(msg, data)
1643
1689
  });
1644
- registerCommonHandlers(this.rpcHandlerManager);
1690
+ registerCommonHandlers(this.rpcHandlerManager, process.cwd());
1645
1691
  }
1646
1692
  socket;
1647
1693
  keepAliveInterval = null;
@@ -1857,7 +1903,7 @@ class PushNotificationClient {
1857
1903
  );
1858
1904
  logger.debug(`Fetched ${response.data.tokens.length} push tokens`);
1859
1905
  response.data.tokens.forEach((token, index) => {
1860
- logger.debug(`[PUSH] Token ${index + 1}: id=${token.id}, token=${token.token}, created=${new Date(token.createdAt).toISOString()}, updated=${new Date(token.updatedAt).toISOString()}`);
1906
+ logger.debug(`[PUSH] Token ${index + 1}: id=${token.id}, created=${new Date(token.createdAt).toISOString()}, updated=${new Date(token.updatedAt).toISOString()}`);
1861
1907
  });
1862
1908
  return response.data.tokens;
1863
1909
  } catch (error) {
@@ -1931,14 +1977,14 @@ class PushNotificationClient {
1931
1977
  const tokens = await this.fetchPushTokens();
1932
1978
  logger.debug(`[PUSH] Fetched ${tokens.length} push tokens`);
1933
1979
  tokens.forEach((token, index) => {
1934
- logger.debug(`[PUSH] Using token ${index + 1}: id=${token.id}, token=${token.token}`);
1980
+ logger.debug(`[PUSH] Using token ${index + 1}: id=${token.id}`);
1935
1981
  });
1936
1982
  if (tokens.length === 0) {
1937
1983
  logger.debug("No push tokens found for user");
1938
1984
  return;
1939
1985
  }
1940
1986
  const messages = tokens.map((token, index) => {
1941
- logger.debug(`[PUSH] Creating message ${index + 1} for token: ${token.token}`);
1987
+ logger.debug(`[PUSH] Creating message ${index + 1} for token`);
1942
1988
  return {
1943
1989
  to: token.token,
1944
1990
  title,
@@ -2135,17 +2181,16 @@ const RawJSONLinesSchema = z.z.discriminatedUnion("type", [
2135
2181
  // Used in sessionScanner.ts
2136
2182
  }).passthrough()
2137
2183
  }).passthrough(),
2138
- // Assistant message - validates message object with usage and content
2184
+ // Assistant message - only validates uuid and type
2185
+ // message object is optional to handle synthetic error messages (isApiErrorMessage: true)
2186
+ // which may have different structure than normal assistant messages
2139
2187
  z.z.object({
2140
2188
  uuid: z.z.string(),
2141
2189
  type: z.z.literal("assistant"),
2142
2190
  message: z.z.object({
2143
- // Entire message used in getMessageKey()
2144
- usage: UsageSchema.optional(),
2191
+ usage: UsageSchema.optional()
2145
2192
  // Used in apiSession.ts
2146
- content: z.z.any()
2147
- // Used in tests
2148
- }).passthrough()
2193
+ }).passthrough().optional()
2149
2194
  }).passthrough(),
2150
2195
  // Summary message - validates summary and leafUuid
2151
2196
  z.z.object({