@zhigang1992/happy-cli 0.12.3 → 0.12.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/dist/{index-DNeoLdzx.mjs → index-BERBU6rR.mjs} +198 -21
- package/dist/{index-y8CVImEp.cjs → index-CHEjP0zg.cjs} +212 -35
- package/dist/index.cjs +6 -6
- package/dist/index.mjs +6 -6
- package/dist/lib.cjs +1 -1
- package/dist/lib.d.cts +118 -4
- package/dist/lib.d.mts +118 -4
- package/dist/lib.mjs +1 -1
- package/dist/{list-D_NjiLPx.mjs → list-BvtUKVTq.mjs} +1 -1
- package/dist/{list-DiamEbqL.cjs → list-DOsBjFRJ.cjs} +1 -1
- package/dist/{prompt-CJh1Mo2A.mjs → prompt-BbMNN7fl.mjs} +1 -1
- package/dist/{prompt-Cu47wZlI.cjs → prompt-Dh_trad0.cjs} +1 -1
- package/dist/{runCodex-B5ZlUUec.mjs → runCodex-CYkmZphO.mjs} +19 -3
- package/dist/{runCodex-DErgypij.cjs → runCodex-DUqqO-m8.cjs} +19 -3
- package/dist/{types-D4_aCy-H.mjs → types-Cw6y7GyQ.mjs} +124 -6
- package/dist/{types-CllU28mx.cjs → types-Q-euvEmG.cjs} +125 -7
- package/package.json +1 -1
package/dist/lib.d.cts
CHANGED
|
@@ -291,6 +291,16 @@ type RawJSONLines = z.infer<typeof RawJSONLinesSchema>;
|
|
|
291
291
|
/**
|
|
292
292
|
* Common RPC types and interfaces for both session and machine clients
|
|
293
293
|
*/
|
|
294
|
+
/**
|
|
295
|
+
* Session context for RPC handlers
|
|
296
|
+
* Contains environment and path information for the current session
|
|
297
|
+
*/
|
|
298
|
+
interface RpcSessionContext {
|
|
299
|
+
/** Working directory path for the session */
|
|
300
|
+
path: string;
|
|
301
|
+
/** Environment variables (includes direnv if available) */
|
|
302
|
+
env: Record<string, string>;
|
|
303
|
+
}
|
|
294
304
|
/**
|
|
295
305
|
* Generic RPC handler function type
|
|
296
306
|
* @template TRequest - The request data type
|
|
@@ -326,7 +336,19 @@ declare class RpcHandlerManager {
|
|
|
326
336
|
private readonly encryptionVariant;
|
|
327
337
|
private readonly logger;
|
|
328
338
|
private socket;
|
|
339
|
+
private sessionContext;
|
|
329
340
|
constructor(config: RpcHandlerConfig);
|
|
341
|
+
/**
|
|
342
|
+
* Set the session context (path and environment)
|
|
343
|
+
* This should be called after direnv environment is loaded
|
|
344
|
+
* @param context - The session context with path and environment
|
|
345
|
+
*/
|
|
346
|
+
setSessionContext(context: RpcSessionContext): void;
|
|
347
|
+
/**
|
|
348
|
+
* Get the current session context
|
|
349
|
+
* @returns The session context or null if not set
|
|
350
|
+
*/
|
|
351
|
+
getSessionContext(): RpcSessionContext | null;
|
|
330
352
|
/**
|
|
331
353
|
* Register an RPC handler for a specific method
|
|
332
354
|
* @param method - The method name (without prefix)
|
|
@@ -423,6 +445,30 @@ declare class ApiSessionClient extends EventEmitter {
|
|
|
423
445
|
*/
|
|
424
446
|
flush(): Promise<void>;
|
|
425
447
|
close(): Promise<void>;
|
|
448
|
+
/**
|
|
449
|
+
* Download and decrypt a blob from the server
|
|
450
|
+
* @param blobId - The blob ID to download
|
|
451
|
+
* @returns The decrypted binary data and metadata, or null if download/decryption fails
|
|
452
|
+
*/
|
|
453
|
+
downloadBlob(blobId: string): Promise<{
|
|
454
|
+
data: Uint8Array;
|
|
455
|
+
mimeType: string;
|
|
456
|
+
size: number;
|
|
457
|
+
} | null>;
|
|
458
|
+
/**
|
|
459
|
+
* Convert an image_ref content block to a Claude API image content block
|
|
460
|
+
* Downloads, decrypts, and base64 encodes the image
|
|
461
|
+
* @param imageRef - The image reference content block
|
|
462
|
+
* @returns Claude API image content block, or null if conversion fails
|
|
463
|
+
*/
|
|
464
|
+
resolveImageRef(imageRef: ImageRefContent): Promise<{
|
|
465
|
+
type: 'image';
|
|
466
|
+
source: {
|
|
467
|
+
type: 'base64';
|
|
468
|
+
media_type: string;
|
|
469
|
+
data: string;
|
|
470
|
+
};
|
|
471
|
+
} | null>;
|
|
426
472
|
}
|
|
427
473
|
|
|
428
474
|
type PermissionMode = 'default' | 'acceptEdits' | 'bypassPermissions' | 'plan';
|
|
@@ -505,9 +551,32 @@ type Machine = {
|
|
|
505
551
|
daemonState: DaemonState | null;
|
|
506
552
|
daemonStateVersion: number;
|
|
507
553
|
};
|
|
554
|
+
/**
|
|
555
|
+
* Image reference content block for user messages (E2E encrypted images)
|
|
556
|
+
*/
|
|
557
|
+
declare const ImageRefContentSchema: z.ZodObject<{
|
|
558
|
+
type: z.ZodLiteral<"image_ref">;
|
|
559
|
+
blobId: z.ZodString;
|
|
560
|
+
mimeType: z.ZodEnum<["image/jpeg", "image/png", "image/gif", "image/webp"]>;
|
|
561
|
+
width: z.ZodOptional<z.ZodNumber>;
|
|
562
|
+
height: z.ZodOptional<z.ZodNumber>;
|
|
563
|
+
}, "strip", z.ZodTypeAny, {
|
|
564
|
+
type: "image_ref";
|
|
565
|
+
blobId: string;
|
|
566
|
+
mimeType: "image/jpeg" | "image/png" | "image/gif" | "image/webp";
|
|
567
|
+
width?: number | undefined;
|
|
568
|
+
height?: number | undefined;
|
|
569
|
+
}, {
|
|
570
|
+
type: "image_ref";
|
|
571
|
+
blobId: string;
|
|
572
|
+
mimeType: "image/jpeg" | "image/png" | "image/gif" | "image/webp";
|
|
573
|
+
width?: number | undefined;
|
|
574
|
+
height?: number | undefined;
|
|
575
|
+
}>;
|
|
576
|
+
type ImageRefContent = z.infer<typeof ImageRefContentSchema>;
|
|
508
577
|
declare const UserMessageSchema: z.ZodObject<{
|
|
509
578
|
role: z.ZodLiteral<"user">;
|
|
510
|
-
content: z.ZodObject<{
|
|
579
|
+
content: z.ZodUnion<[z.ZodObject<{
|
|
511
580
|
type: z.ZodLiteral<"text">;
|
|
512
581
|
text: z.ZodString;
|
|
513
582
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -516,7 +585,34 @@ declare const UserMessageSchema: z.ZodObject<{
|
|
|
516
585
|
}, {
|
|
517
586
|
type: "text";
|
|
518
587
|
text: string;
|
|
519
|
-
}
|
|
588
|
+
}>, z.ZodArray<z.ZodUnion<[z.ZodObject<{
|
|
589
|
+
type: z.ZodLiteral<"text">;
|
|
590
|
+
text: z.ZodString;
|
|
591
|
+
}, "strip", z.ZodTypeAny, {
|
|
592
|
+
type: "text";
|
|
593
|
+
text: string;
|
|
594
|
+
}, {
|
|
595
|
+
type: "text";
|
|
596
|
+
text: string;
|
|
597
|
+
}>, z.ZodObject<{
|
|
598
|
+
type: z.ZodLiteral<"image_ref">;
|
|
599
|
+
blobId: z.ZodString;
|
|
600
|
+
mimeType: z.ZodEnum<["image/jpeg", "image/png", "image/gif", "image/webp"]>;
|
|
601
|
+
width: z.ZodOptional<z.ZodNumber>;
|
|
602
|
+
height: z.ZodOptional<z.ZodNumber>;
|
|
603
|
+
}, "strip", z.ZodTypeAny, {
|
|
604
|
+
type: "image_ref";
|
|
605
|
+
blobId: string;
|
|
606
|
+
mimeType: "image/jpeg" | "image/png" | "image/gif" | "image/webp";
|
|
607
|
+
width?: number | undefined;
|
|
608
|
+
height?: number | undefined;
|
|
609
|
+
}, {
|
|
610
|
+
type: "image_ref";
|
|
611
|
+
blobId: string;
|
|
612
|
+
mimeType: "image/jpeg" | "image/png" | "image/gif" | "image/webp";
|
|
613
|
+
width?: number | undefined;
|
|
614
|
+
height?: number | undefined;
|
|
615
|
+
}>]>, "many">]>;
|
|
520
616
|
localKey: z.ZodOptional<z.ZodString>;
|
|
521
617
|
meta: z.ZodOptional<z.ZodObject<{
|
|
522
618
|
sentFrom: z.ZodOptional<z.ZodString>;
|
|
@@ -550,7 +646,16 @@ declare const UserMessageSchema: z.ZodObject<{
|
|
|
550
646
|
content: {
|
|
551
647
|
type: "text";
|
|
552
648
|
text: string;
|
|
553
|
-
}
|
|
649
|
+
} | ({
|
|
650
|
+
type: "text";
|
|
651
|
+
text: string;
|
|
652
|
+
} | {
|
|
653
|
+
type: "image_ref";
|
|
654
|
+
blobId: string;
|
|
655
|
+
mimeType: "image/jpeg" | "image/png" | "image/gif" | "image/webp";
|
|
656
|
+
width?: number | undefined;
|
|
657
|
+
height?: number | undefined;
|
|
658
|
+
})[];
|
|
554
659
|
role: "user";
|
|
555
660
|
localKey?: string | undefined;
|
|
556
661
|
meta?: {
|
|
@@ -567,7 +672,16 @@ declare const UserMessageSchema: z.ZodObject<{
|
|
|
567
672
|
content: {
|
|
568
673
|
type: "text";
|
|
569
674
|
text: string;
|
|
570
|
-
}
|
|
675
|
+
} | ({
|
|
676
|
+
type: "text";
|
|
677
|
+
text: string;
|
|
678
|
+
} | {
|
|
679
|
+
type: "image_ref";
|
|
680
|
+
blobId: string;
|
|
681
|
+
mimeType: "image/jpeg" | "image/png" | "image/gif" | "image/webp";
|
|
682
|
+
width?: number | undefined;
|
|
683
|
+
height?: number | undefined;
|
|
684
|
+
})[];
|
|
571
685
|
role: "user";
|
|
572
686
|
localKey?: string | undefined;
|
|
573
687
|
meta?: {
|
package/dist/lib.d.mts
CHANGED
|
@@ -291,6 +291,16 @@ type RawJSONLines = z.infer<typeof RawJSONLinesSchema>;
|
|
|
291
291
|
/**
|
|
292
292
|
* Common RPC types and interfaces for both session and machine clients
|
|
293
293
|
*/
|
|
294
|
+
/**
|
|
295
|
+
* Session context for RPC handlers
|
|
296
|
+
* Contains environment and path information for the current session
|
|
297
|
+
*/
|
|
298
|
+
interface RpcSessionContext {
|
|
299
|
+
/** Working directory path for the session */
|
|
300
|
+
path: string;
|
|
301
|
+
/** Environment variables (includes direnv if available) */
|
|
302
|
+
env: Record<string, string>;
|
|
303
|
+
}
|
|
294
304
|
/**
|
|
295
305
|
* Generic RPC handler function type
|
|
296
306
|
* @template TRequest - The request data type
|
|
@@ -326,7 +336,19 @@ declare class RpcHandlerManager {
|
|
|
326
336
|
private readonly encryptionVariant;
|
|
327
337
|
private readonly logger;
|
|
328
338
|
private socket;
|
|
339
|
+
private sessionContext;
|
|
329
340
|
constructor(config: RpcHandlerConfig);
|
|
341
|
+
/**
|
|
342
|
+
* Set the session context (path and environment)
|
|
343
|
+
* This should be called after direnv environment is loaded
|
|
344
|
+
* @param context - The session context with path and environment
|
|
345
|
+
*/
|
|
346
|
+
setSessionContext(context: RpcSessionContext): void;
|
|
347
|
+
/**
|
|
348
|
+
* Get the current session context
|
|
349
|
+
* @returns The session context or null if not set
|
|
350
|
+
*/
|
|
351
|
+
getSessionContext(): RpcSessionContext | null;
|
|
330
352
|
/**
|
|
331
353
|
* Register an RPC handler for a specific method
|
|
332
354
|
* @param method - The method name (without prefix)
|
|
@@ -423,6 +445,30 @@ declare class ApiSessionClient extends EventEmitter {
|
|
|
423
445
|
*/
|
|
424
446
|
flush(): Promise<void>;
|
|
425
447
|
close(): Promise<void>;
|
|
448
|
+
/**
|
|
449
|
+
* Download and decrypt a blob from the server
|
|
450
|
+
* @param blobId - The blob ID to download
|
|
451
|
+
* @returns The decrypted binary data and metadata, or null if download/decryption fails
|
|
452
|
+
*/
|
|
453
|
+
downloadBlob(blobId: string): Promise<{
|
|
454
|
+
data: Uint8Array;
|
|
455
|
+
mimeType: string;
|
|
456
|
+
size: number;
|
|
457
|
+
} | null>;
|
|
458
|
+
/**
|
|
459
|
+
* Convert an image_ref content block to a Claude API image content block
|
|
460
|
+
* Downloads, decrypts, and base64 encodes the image
|
|
461
|
+
* @param imageRef - The image reference content block
|
|
462
|
+
* @returns Claude API image content block, or null if conversion fails
|
|
463
|
+
*/
|
|
464
|
+
resolveImageRef(imageRef: ImageRefContent): Promise<{
|
|
465
|
+
type: 'image';
|
|
466
|
+
source: {
|
|
467
|
+
type: 'base64';
|
|
468
|
+
media_type: string;
|
|
469
|
+
data: string;
|
|
470
|
+
};
|
|
471
|
+
} | null>;
|
|
426
472
|
}
|
|
427
473
|
|
|
428
474
|
type PermissionMode = 'default' | 'acceptEdits' | 'bypassPermissions' | 'plan';
|
|
@@ -505,9 +551,32 @@ type Machine = {
|
|
|
505
551
|
daemonState: DaemonState | null;
|
|
506
552
|
daemonStateVersion: number;
|
|
507
553
|
};
|
|
554
|
+
/**
|
|
555
|
+
* Image reference content block for user messages (E2E encrypted images)
|
|
556
|
+
*/
|
|
557
|
+
declare const ImageRefContentSchema: z.ZodObject<{
|
|
558
|
+
type: z.ZodLiteral<"image_ref">;
|
|
559
|
+
blobId: z.ZodString;
|
|
560
|
+
mimeType: z.ZodEnum<["image/jpeg", "image/png", "image/gif", "image/webp"]>;
|
|
561
|
+
width: z.ZodOptional<z.ZodNumber>;
|
|
562
|
+
height: z.ZodOptional<z.ZodNumber>;
|
|
563
|
+
}, "strip", z.ZodTypeAny, {
|
|
564
|
+
type: "image_ref";
|
|
565
|
+
blobId: string;
|
|
566
|
+
mimeType: "image/jpeg" | "image/png" | "image/gif" | "image/webp";
|
|
567
|
+
width?: number | undefined;
|
|
568
|
+
height?: number | undefined;
|
|
569
|
+
}, {
|
|
570
|
+
type: "image_ref";
|
|
571
|
+
blobId: string;
|
|
572
|
+
mimeType: "image/jpeg" | "image/png" | "image/gif" | "image/webp";
|
|
573
|
+
width?: number | undefined;
|
|
574
|
+
height?: number | undefined;
|
|
575
|
+
}>;
|
|
576
|
+
type ImageRefContent = z.infer<typeof ImageRefContentSchema>;
|
|
508
577
|
declare const UserMessageSchema: z.ZodObject<{
|
|
509
578
|
role: z.ZodLiteral<"user">;
|
|
510
|
-
content: z.ZodObject<{
|
|
579
|
+
content: z.ZodUnion<[z.ZodObject<{
|
|
511
580
|
type: z.ZodLiteral<"text">;
|
|
512
581
|
text: z.ZodString;
|
|
513
582
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -516,7 +585,34 @@ declare const UserMessageSchema: z.ZodObject<{
|
|
|
516
585
|
}, {
|
|
517
586
|
type: "text";
|
|
518
587
|
text: string;
|
|
519
|
-
}
|
|
588
|
+
}>, z.ZodArray<z.ZodUnion<[z.ZodObject<{
|
|
589
|
+
type: z.ZodLiteral<"text">;
|
|
590
|
+
text: z.ZodString;
|
|
591
|
+
}, "strip", z.ZodTypeAny, {
|
|
592
|
+
type: "text";
|
|
593
|
+
text: string;
|
|
594
|
+
}, {
|
|
595
|
+
type: "text";
|
|
596
|
+
text: string;
|
|
597
|
+
}>, z.ZodObject<{
|
|
598
|
+
type: z.ZodLiteral<"image_ref">;
|
|
599
|
+
blobId: z.ZodString;
|
|
600
|
+
mimeType: z.ZodEnum<["image/jpeg", "image/png", "image/gif", "image/webp"]>;
|
|
601
|
+
width: z.ZodOptional<z.ZodNumber>;
|
|
602
|
+
height: z.ZodOptional<z.ZodNumber>;
|
|
603
|
+
}, "strip", z.ZodTypeAny, {
|
|
604
|
+
type: "image_ref";
|
|
605
|
+
blobId: string;
|
|
606
|
+
mimeType: "image/jpeg" | "image/png" | "image/gif" | "image/webp";
|
|
607
|
+
width?: number | undefined;
|
|
608
|
+
height?: number | undefined;
|
|
609
|
+
}, {
|
|
610
|
+
type: "image_ref";
|
|
611
|
+
blobId: string;
|
|
612
|
+
mimeType: "image/jpeg" | "image/png" | "image/gif" | "image/webp";
|
|
613
|
+
width?: number | undefined;
|
|
614
|
+
height?: number | undefined;
|
|
615
|
+
}>]>, "many">]>;
|
|
520
616
|
localKey: z.ZodOptional<z.ZodString>;
|
|
521
617
|
meta: z.ZodOptional<z.ZodObject<{
|
|
522
618
|
sentFrom: z.ZodOptional<z.ZodString>;
|
|
@@ -550,7 +646,16 @@ declare const UserMessageSchema: z.ZodObject<{
|
|
|
550
646
|
content: {
|
|
551
647
|
type: "text";
|
|
552
648
|
text: string;
|
|
553
|
-
}
|
|
649
|
+
} | ({
|
|
650
|
+
type: "text";
|
|
651
|
+
text: string;
|
|
652
|
+
} | {
|
|
653
|
+
type: "image_ref";
|
|
654
|
+
blobId: string;
|
|
655
|
+
mimeType: "image/jpeg" | "image/png" | "image/gif" | "image/webp";
|
|
656
|
+
width?: number | undefined;
|
|
657
|
+
height?: number | undefined;
|
|
658
|
+
})[];
|
|
554
659
|
role: "user";
|
|
555
660
|
localKey?: string | undefined;
|
|
556
661
|
meta?: {
|
|
@@ -567,7 +672,16 @@ declare const UserMessageSchema: z.ZodObject<{
|
|
|
567
672
|
content: {
|
|
568
673
|
type: "text";
|
|
569
674
|
text: string;
|
|
570
|
-
}
|
|
675
|
+
} | ({
|
|
676
|
+
type: "text";
|
|
677
|
+
text: string;
|
|
678
|
+
} | {
|
|
679
|
+
type: "image_ref";
|
|
680
|
+
blobId: string;
|
|
681
|
+
mimeType: "image/jpeg" | "image/png" | "image/gif" | "image/webp";
|
|
682
|
+
width?: number | undefined;
|
|
683
|
+
height?: number | undefined;
|
|
684
|
+
})[];
|
|
571
685
|
role: "user";
|
|
572
686
|
localKey?: string | undefined;
|
|
573
687
|
meta?: {
|
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-
|
|
1
|
+
export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-Cw6y7GyQ.mjs';
|
|
2
2
|
import 'axios';
|
|
3
3
|
import 'chalk';
|
|
4
4
|
import 'fs';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as configuration, l as logger, d as decodeBase64, b as decrypt, f as formatTimeAgo, e as libsodiumDecryptFromPublicKey } from './types-
|
|
1
|
+
import { c as configuration, l as logger, d as decodeBase64, b as decrypt, f as formatTimeAgo, e as libsodiumDecryptFromPublicKey } from './types-Cw6y7GyQ.mjs';
|
|
2
2
|
import axios from 'axios';
|
|
3
3
|
import { existsSync, readdirSync, statSync, readFileSync } from 'fs';
|
|
4
4
|
import { join } from 'path';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as configuration, b as decrypt, d as decodeBase64, l as logger, g as encodeBase64, h as encrypt } from './types-
|
|
1
|
+
import { c as configuration, b as decrypt, d as decodeBase64, l as logger, g as encodeBase64, h as encrypt } from './types-Cw6y7GyQ.mjs';
|
|
2
2
|
import axios from 'axios';
|
|
3
3
|
import { io } from 'socket.io-client';
|
|
4
4
|
import 'chalk';
|
|
@@ -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, i as packageJson } from './types-
|
|
3
|
+
import { l as logger, A as ApiClient, r as readSettings, p as projectPath, c as configuration, i as packageJson } from './types-Cw6y7GyQ.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-
|
|
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-BERBU6rR.mjs';
|
|
11
11
|
import os from 'node:os';
|
|
12
12
|
import { resolve, join } from 'node:path';
|
|
13
13
|
import fs from 'node:fs';
|
|
@@ -752,6 +752,21 @@ const CodexDisplay = ({ messageBuffer, logPath, onExit }) => {
|
|
|
752
752
|
));
|
|
753
753
|
};
|
|
754
754
|
|
|
755
|
+
function extractTextFromContent(content) {
|
|
756
|
+
if (!Array.isArray(content)) {
|
|
757
|
+
if (content.type === "text") {
|
|
758
|
+
return content.text;
|
|
759
|
+
}
|
|
760
|
+
return "";
|
|
761
|
+
}
|
|
762
|
+
const textParts = [];
|
|
763
|
+
for (const block of content) {
|
|
764
|
+
if (block.type === "text") {
|
|
765
|
+
textParts.push(block.text);
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
return textParts.join("\n");
|
|
769
|
+
}
|
|
755
770
|
function emitReadyIfIdle({ pending, queueSize, shouldExit, sendReady, notify }) {
|
|
756
771
|
if (shouldExit) {
|
|
757
772
|
return false;
|
|
@@ -847,7 +862,8 @@ async function runCodex(opts) {
|
|
|
847
862
|
permissionMode: messagePermissionMode || "default",
|
|
848
863
|
model: messageModel
|
|
849
864
|
};
|
|
850
|
-
|
|
865
|
+
const textContent = extractTextFromContent(message.content);
|
|
866
|
+
messageQueue.push(textContent, enhancedMode);
|
|
851
867
|
});
|
|
852
868
|
let thinking = false;
|
|
853
869
|
session.keepAlive(thinking, "remote");
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
var ink = require('ink');
|
|
4
4
|
var React = require('react');
|
|
5
|
-
var types = require('./types-
|
|
5
|
+
var types = require('./types-Q-euvEmG.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-
|
|
12
|
+
var index = require('./index-CHEjP0zg.cjs');
|
|
13
13
|
var os = require('node:os');
|
|
14
14
|
var node_path = require('node:path');
|
|
15
15
|
var fs = require('node:fs');
|
|
@@ -754,6 +754,21 @@ const CodexDisplay = ({ messageBuffer, logPath, onExit }) => {
|
|
|
754
754
|
));
|
|
755
755
|
};
|
|
756
756
|
|
|
757
|
+
function extractTextFromContent(content) {
|
|
758
|
+
if (!Array.isArray(content)) {
|
|
759
|
+
if (content.type === "text") {
|
|
760
|
+
return content.text;
|
|
761
|
+
}
|
|
762
|
+
return "";
|
|
763
|
+
}
|
|
764
|
+
const textParts = [];
|
|
765
|
+
for (const block of content) {
|
|
766
|
+
if (block.type === "text") {
|
|
767
|
+
textParts.push(block.text);
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
return textParts.join("\n");
|
|
771
|
+
}
|
|
757
772
|
function emitReadyIfIdle({ pending, queueSize, shouldExit, sendReady, notify }) {
|
|
758
773
|
if (shouldExit) {
|
|
759
774
|
return false;
|
|
@@ -849,7 +864,8 @@ async function runCodex(opts) {
|
|
|
849
864
|
permissionMode: messagePermissionMode || "default",
|
|
850
865
|
model: messageModel
|
|
851
866
|
};
|
|
852
|
-
|
|
867
|
+
const textContent = extractTextFromContent(message.content);
|
|
868
|
+
messageQueue.push(textContent, enhancedMode);
|
|
853
869
|
});
|
|
854
870
|
let thinking = false;
|
|
855
871
|
session.keepAlive(thinking, "remote");
|
|
@@ -20,7 +20,7 @@ import { fileURLToPath } from 'url';
|
|
|
20
20
|
import { Expo } from 'expo-server-sdk';
|
|
21
21
|
|
|
22
22
|
var name = "@zhigang1992/happy-cli";
|
|
23
|
-
var version = "0.12.
|
|
23
|
+
var version = "0.12.4";
|
|
24
24
|
var description = "Mobile and Web client for Claude Code and Codex";
|
|
25
25
|
var author = "Kirill Dubovitskiy";
|
|
26
26
|
var license = "MIT";
|
|
@@ -311,6 +311,31 @@ function decryptWithDataKey(bundle, dataKey) {
|
|
|
311
311
|
return null;
|
|
312
312
|
}
|
|
313
313
|
}
|
|
314
|
+
function decryptBlobWithDataKey(bundle, dataKey) {
|
|
315
|
+
if (bundle.length < 1) {
|
|
316
|
+
return null;
|
|
317
|
+
}
|
|
318
|
+
if (bundle[0] !== 0) {
|
|
319
|
+
return null;
|
|
320
|
+
}
|
|
321
|
+
if (bundle.length < 12 + 16 + 1) {
|
|
322
|
+
return null;
|
|
323
|
+
}
|
|
324
|
+
const nonce = bundle.slice(1, 13);
|
|
325
|
+
const authTag = bundle.slice(bundle.length - 16);
|
|
326
|
+
const ciphertext = bundle.slice(13, bundle.length - 16);
|
|
327
|
+
try {
|
|
328
|
+
const decipher = createDecipheriv("aes-256-gcm", dataKey, nonce);
|
|
329
|
+
decipher.setAuthTag(authTag);
|
|
330
|
+
const decrypted = Buffer.concat([
|
|
331
|
+
decipher.update(ciphertext),
|
|
332
|
+
decipher.final()
|
|
333
|
+
]);
|
|
334
|
+
return new Uint8Array(decrypted);
|
|
335
|
+
} catch (error) {
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
314
339
|
function encrypt(key, variant, data) {
|
|
315
340
|
if (variant === "legacy") {
|
|
316
341
|
return encryptLegacy(data, key);
|
|
@@ -852,12 +877,27 @@ z$1.object({
|
|
|
852
877
|
agentStateVersion: z$1.number()
|
|
853
878
|
})
|
|
854
879
|
});
|
|
880
|
+
const TextContentSchema = z$1.object({
|
|
881
|
+
type: z$1.literal("text"),
|
|
882
|
+
text: z$1.string()
|
|
883
|
+
});
|
|
884
|
+
const ImageRefContentSchema = z$1.object({
|
|
885
|
+
type: z$1.literal("image_ref"),
|
|
886
|
+
blobId: z$1.string(),
|
|
887
|
+
mimeType: z$1.enum(["image/jpeg", "image/png", "image/gif", "image/webp"]),
|
|
888
|
+
width: z$1.number().optional(),
|
|
889
|
+
height: z$1.number().optional()
|
|
890
|
+
});
|
|
891
|
+
const ContentBlockSchema = z$1.union([TextContentSchema, ImageRefContentSchema]);
|
|
892
|
+
const UserMessageContentSchema = z$1.union([
|
|
893
|
+
TextContentSchema,
|
|
894
|
+
// Legacy: single text content
|
|
895
|
+
z$1.array(ContentBlockSchema)
|
|
896
|
+
// New: array of content blocks
|
|
897
|
+
]);
|
|
855
898
|
const UserMessageSchema = z$1.object({
|
|
856
899
|
role: z$1.literal("user"),
|
|
857
|
-
content:
|
|
858
|
-
type: z$1.literal("text"),
|
|
859
|
-
text: z$1.string()
|
|
860
|
-
}),
|
|
900
|
+
content: UserMessageContentSchema,
|
|
861
901
|
localKey: z$1.string().optional(),
|
|
862
902
|
// Mobile messages include this
|
|
863
903
|
meta: MessageMetaSchema.optional()
|
|
@@ -969,12 +1009,29 @@ class RpcHandlerManager {
|
|
|
969
1009
|
encryptionVariant;
|
|
970
1010
|
logger;
|
|
971
1011
|
socket = null;
|
|
1012
|
+
sessionContext = null;
|
|
972
1013
|
constructor(config) {
|
|
973
1014
|
this.scopePrefix = config.scopePrefix;
|
|
974
1015
|
this.encryptionKey = config.encryptionKey;
|
|
975
1016
|
this.encryptionVariant = config.encryptionVariant;
|
|
976
1017
|
this.logger = config.logger || ((msg, data) => logger.debug(msg, data));
|
|
977
1018
|
}
|
|
1019
|
+
/**
|
|
1020
|
+
* Set the session context (path and environment)
|
|
1021
|
+
* This should be called after direnv environment is loaded
|
|
1022
|
+
* @param context - The session context with path and environment
|
|
1023
|
+
*/
|
|
1024
|
+
setSessionContext(context) {
|
|
1025
|
+
this.sessionContext = context;
|
|
1026
|
+
this.logger("[RPC] Session context set", { path: context.path, envVarCount: Object.keys(context.env).length });
|
|
1027
|
+
}
|
|
1028
|
+
/**
|
|
1029
|
+
* Get the current session context
|
|
1030
|
+
* @returns The session context or null if not set
|
|
1031
|
+
*/
|
|
1032
|
+
getSessionContext() {
|
|
1033
|
+
return this.sessionContext;
|
|
1034
|
+
}
|
|
978
1035
|
/**
|
|
979
1036
|
* Register an RPC handler for a specific method
|
|
980
1037
|
* @param method - The method name (without prefix)
|
|
@@ -1150,10 +1207,13 @@ function registerCommonHandlers(rpcHandlerManager) {
|
|
|
1150
1207
|
rpcHandlerManager.registerHandler("bash", async (data) => {
|
|
1151
1208
|
logger.debug("Shell command request:", data.command);
|
|
1152
1209
|
try {
|
|
1210
|
+
const sessionContext = rpcHandlerManager.getSessionContext();
|
|
1153
1211
|
const options = {
|
|
1154
1212
|
cwd: data.cwd,
|
|
1155
|
-
timeout: data.timeout || 3e4
|
|
1213
|
+
timeout: data.timeout || 3e4,
|
|
1156
1214
|
// Default 30 seconds timeout
|
|
1215
|
+
// Use session environment if available, otherwise inherit process.env
|
|
1216
|
+
env: sessionContext?.env ?? process.env
|
|
1157
1217
|
};
|
|
1158
1218
|
const { stdout, stderr } = await execAsync(data.command, options);
|
|
1159
1219
|
return {
|
|
@@ -1683,6 +1743,64 @@ class ApiSessionClient extends EventEmitter {
|
|
|
1683
1743
|
logger.debug("[API] socket.close() called");
|
|
1684
1744
|
this.socket.close();
|
|
1685
1745
|
}
|
|
1746
|
+
/**
|
|
1747
|
+
* Download and decrypt a blob from the server
|
|
1748
|
+
* @param blobId - The blob ID to download
|
|
1749
|
+
* @returns The decrypted binary data and metadata, or null if download/decryption fails
|
|
1750
|
+
*/
|
|
1751
|
+
async downloadBlob(blobId) {
|
|
1752
|
+
try {
|
|
1753
|
+
const response = await axios.get(
|
|
1754
|
+
`${configuration.serverUrl}/v1/sessions/${this.sessionId}/blobs/${blobId}`,
|
|
1755
|
+
{
|
|
1756
|
+
headers: {
|
|
1757
|
+
"Authorization": `Bearer ${this.token}`
|
|
1758
|
+
},
|
|
1759
|
+
responseType: "arraybuffer"
|
|
1760
|
+
}
|
|
1761
|
+
);
|
|
1762
|
+
const encryptedData = new Uint8Array(response.data);
|
|
1763
|
+
const mimeType = response.headers["x-blob-mimetype"];
|
|
1764
|
+
const originalSize = parseInt(response.headers["x-blob-size"], 10);
|
|
1765
|
+
if (this.encryptionVariant !== "dataKey") {
|
|
1766
|
+
logger.debug("[API] Cannot decrypt blob: session uses legacy encryption");
|
|
1767
|
+
return null;
|
|
1768
|
+
}
|
|
1769
|
+
const decryptedData = decryptBlobWithDataKey(encryptedData, this.encryptionKey);
|
|
1770
|
+
if (!decryptedData) {
|
|
1771
|
+
logger.debug("[API] Failed to decrypt blob");
|
|
1772
|
+
return null;
|
|
1773
|
+
}
|
|
1774
|
+
return {
|
|
1775
|
+
data: decryptedData,
|
|
1776
|
+
mimeType,
|
|
1777
|
+
size: originalSize
|
|
1778
|
+
};
|
|
1779
|
+
} catch (error) {
|
|
1780
|
+
logger.debug("[API] Failed to download blob:", error);
|
|
1781
|
+
return null;
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
/**
|
|
1785
|
+
* Convert an image_ref content block to a Claude API image content block
|
|
1786
|
+
* Downloads, decrypts, and base64 encodes the image
|
|
1787
|
+
* @param imageRef - The image reference content block
|
|
1788
|
+
* @returns Claude API image content block, or null if conversion fails
|
|
1789
|
+
*/
|
|
1790
|
+
async resolveImageRef(imageRef) {
|
|
1791
|
+
const blob = await this.downloadBlob(imageRef.blobId);
|
|
1792
|
+
if (!blob) {
|
|
1793
|
+
return null;
|
|
1794
|
+
}
|
|
1795
|
+
return {
|
|
1796
|
+
type: "image",
|
|
1797
|
+
source: {
|
|
1798
|
+
type: "base64",
|
|
1799
|
+
media_type: blob.mimeType,
|
|
1800
|
+
data: Buffer.from(blob.data).toString("base64")
|
|
1801
|
+
}
|
|
1802
|
+
};
|
|
1803
|
+
}
|
|
1686
1804
|
}
|
|
1687
1805
|
|
|
1688
1806
|
class ApiMachineClient {
|