@cjhyy/code-shell-web 0.8.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/README.md +42 -0
- package/dist/hooks/remoteAppSync.d.ts +21 -0
- package/dist/hooks/remoteAppSync.js +102 -0
- package/dist/hooks/useRemoteApp.d.ts +89 -0
- package/dist/hooks/useRemoteApp.js +1015 -0
- package/dist/hooks/useRemoteSocket.d.ts +25 -0
- package/dist/hooks/useRemoteSocket.js +267 -0
- package/dist/i18n/mobile.d.ts +323 -0
- package/dist/i18n/mobile.js +323 -0
- package/dist/i18n/translate.d.ts +351 -0
- package/dist/i18n/translate.js +35 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +28 -0
- package/dist/lib/deviceCredential.d.ts +14 -0
- package/dist/lib/deviceCredential.js +19 -0
- package/dist/lib/format.d.ts +26 -0
- package/dist/lib/format.js +96 -0
- package/dist/lib/messageMappers.d.ts +37 -0
- package/dist/lib/messageMappers.js +145 -0
- package/dist/lib/mobileAttachments.d.ts +23 -0
- package/dist/lib/mobileAttachments.js +121 -0
- package/dist/lib/pairing.d.ts +6 -0
- package/dist/lib/pairing.js +8 -0
- package/dist/lib/riskClassify.d.ts +5 -0
- package/dist/lib/riskClassify.js +56 -0
- package/dist/lib/storage.d.ts +10 -0
- package/dist/lib/storage.js +53 -0
- package/dist/lib/streamReducer.d.ts +90 -0
- package/dist/lib/streamReducer.js +564 -0
- package/dist/lib/uiLanguage.d.ts +15 -0
- package/dist/lib/uiLanguage.js +34 -0
- package/dist-app/assets/index-CbC5kEGZ.js +11 -0
- package/dist-app/assets/index-xwzva9ZI.css +1 -0
- package/dist-app/index.html +13 -0
- package/package.json +55 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const deviceStore: {
|
|
2
|
+
readonly getId: () => string;
|
|
3
|
+
readonly setId: (v: string) => void;
|
|
4
|
+
readonly clearId: () => void;
|
|
5
|
+
/** Get the stable per-browser secret, minting+persisting one on first use.
|
|
6
|
+
* Mirrors the old getSecret() so existing devices keep the same secret. */
|
|
7
|
+
readonly getOrCreateSecret: (mint: () => string) => string;
|
|
8
|
+
/** Device display name, defaulting to a platform-derived label on first use. */
|
|
9
|
+
readonly getOrCreateName: () => string;
|
|
10
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin typed wrapper over localStorage for the mobile remote's persisted
|
|
3
|
+
* device identity. Keys keep the historical `cs.*` names so an already-paired
|
|
4
|
+
* phone (paired against the old inline UI) keeps working after the rebuild.
|
|
5
|
+
*/
|
|
6
|
+
import { translate } from "../i18n/translate.js";
|
|
7
|
+
import { loadUILanguage } from "./uiLanguage.js";
|
|
8
|
+
const K = {
|
|
9
|
+
deviceId: "cs.deviceId",
|
|
10
|
+
deviceSecret: "cs.deviceSecret",
|
|
11
|
+
deviceName: "cs.deviceName",
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Best-effort localStorage write. On a quota-constrained mobile browser
|
|
15
|
+
* (iOS/Android default ~5MB) setItem throws QuotaExceededError; since these
|
|
16
|
+
* calls run synchronously inside ws.onopen (the auth handshake), an uncaught
|
|
17
|
+
* throw aborts onopen mid-flight → handshake never sent → blank app, no retry.
|
|
18
|
+
* Swallow the write failure and let the caller proceed with the in-memory value;
|
|
19
|
+
* losing persistence only means a fresh secret/name next session.
|
|
20
|
+
*/
|
|
21
|
+
function safeSet(key, value) {
|
|
22
|
+
try {
|
|
23
|
+
localStorage.setItem(key, value);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
/* quota / disabled storage — best-effort, value still returned to caller */
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export const deviceStore = {
|
|
30
|
+
getId: () => localStorage.getItem(K.deviceId) ?? "",
|
|
31
|
+
setId: (v) => safeSet(K.deviceId, v),
|
|
32
|
+
clearId: () => localStorage.removeItem(K.deviceId),
|
|
33
|
+
/** Get the stable per-browser secret, minting+persisting one on first use.
|
|
34
|
+
* Mirrors the old getSecret() so existing devices keep the same secret. */
|
|
35
|
+
getOrCreateSecret: (mint) => {
|
|
36
|
+
let s = localStorage.getItem(K.deviceSecret);
|
|
37
|
+
if (!s) {
|
|
38
|
+
s = mint();
|
|
39
|
+
safeSet(K.deviceSecret, s);
|
|
40
|
+
}
|
|
41
|
+
return s;
|
|
42
|
+
},
|
|
43
|
+
/** Device display name, defaulting to a platform-derived label on first use. */
|
|
44
|
+
getOrCreateName: () => {
|
|
45
|
+
let n = localStorage.getItem(K.deviceName);
|
|
46
|
+
if (!n) {
|
|
47
|
+
const platform = (typeof navigator !== "undefined" && navigator.platform) || "Phone";
|
|
48
|
+
n = translate(loadUILanguage(), "mobile.storage.browserDevice", { platform });
|
|
49
|
+
safeSet(K.deviceName, n);
|
|
50
|
+
}
|
|
51
|
+
return n;
|
|
52
|
+
},
|
|
53
|
+
};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mobile chat reducer: folds the worker→renderer JSON-RPC stream (the SAME
|
|
3
|
+
* lines the desktop renderer receives, mirrored via RemoteHostManager.
|
|
4
|
+
* broadcastRaw) into a flat list of view items. It also consumes `session.
|
|
5
|
+
* history` replay, which emits the identical `agent/streamEvent` envelopes, so
|
|
6
|
+
* one reducer serves both live and replay (design §4).
|
|
7
|
+
*
|
|
8
|
+
* Event names mirror core's StreamEvent union (packages/core/src/types.ts):
|
|
9
|
+
* stream_request_start | text_delta | thinking_delta | tool_use_start |
|
|
10
|
+
* tool_use_args_delta | tool_result | tool_summary | assistant_message |
|
|
11
|
+
* turn_complete | goal_progress | task_update | agent_start | agent_end |
|
|
12
|
+
* error | session_title …
|
|
13
|
+
*
|
|
14
|
+
* Subagent events carry an optional `agentId`. We tag items with it so a future
|
|
15
|
+
* UI can scope subagent rows (see commit fbe6f68 — task_update must be isolated
|
|
16
|
+
* by agentId so a subagent never clobbers the main list).
|
|
17
|
+
*/
|
|
18
|
+
export type RunState = "idle" | "running" | "waiting" | "completed" | "error";
|
|
19
|
+
export interface UserAttachmentSummary {
|
|
20
|
+
name: string;
|
|
21
|
+
mime?: string;
|
|
22
|
+
size: number;
|
|
23
|
+
}
|
|
24
|
+
export type ChatItem = {
|
|
25
|
+
kind: "user";
|
|
26
|
+
id: string;
|
|
27
|
+
text: string;
|
|
28
|
+
attachments?: UserAttachmentSummary[];
|
|
29
|
+
} | {
|
|
30
|
+
kind: "assistant";
|
|
31
|
+
id: string;
|
|
32
|
+
text: string;
|
|
33
|
+
reasoning: string;
|
|
34
|
+
done: boolean;
|
|
35
|
+
agentId?: string;
|
|
36
|
+
} | {
|
|
37
|
+
kind: "tool";
|
|
38
|
+
id: string;
|
|
39
|
+
name: string;
|
|
40
|
+
args?: Record<string, unknown>;
|
|
41
|
+
result?: string;
|
|
42
|
+
error?: boolean;
|
|
43
|
+
summary?: string;
|
|
44
|
+
done: boolean;
|
|
45
|
+
agentId?: string;
|
|
46
|
+
} | {
|
|
47
|
+
kind: "subagent";
|
|
48
|
+
id: string;
|
|
49
|
+
agentId: string;
|
|
50
|
+
label: string;
|
|
51
|
+
status: string;
|
|
52
|
+
} | {
|
|
53
|
+
kind: "system_error";
|
|
54
|
+
id: string;
|
|
55
|
+
text: string;
|
|
56
|
+
};
|
|
57
|
+
export interface ChatState {
|
|
58
|
+
items: ChatItem[];
|
|
59
|
+
run: RunState;
|
|
60
|
+
/** Latest goal-progress status line, if any (display-only). */
|
|
61
|
+
goal?: string;
|
|
62
|
+
/** Identity of the active goal banner; absent for legacy events. */
|
|
63
|
+
goalId?: string;
|
|
64
|
+
/** Whether the active goal is paused. */
|
|
65
|
+
goalPaused?: boolean;
|
|
66
|
+
/** Monotonic Goal edit generation used to fence late events. */
|
|
67
|
+
goalRevision?: number;
|
|
68
|
+
sessionId?: string;
|
|
69
|
+
/** Per-session title pushed via session_title. */
|
|
70
|
+
title?: string;
|
|
71
|
+
/** Internal: id of the assistant item currently accumulating text/thinking
|
|
72
|
+
* deltas, keyed by agentId ("" = the main agent). Keying by agent keeps a
|
|
73
|
+
* concurrently-streaming subagent's text out of the main bubble (and vice
|
|
74
|
+
* versa) — mirrors the renderer's per-agent message routing. */
|
|
75
|
+
liveByAgent: Record<string, string>;
|
|
76
|
+
/** Internal: monotonic counter for fresh ids (replaces Date.now/random,
|
|
77
|
+
* which would make replay non-deterministic). */
|
|
78
|
+
seq: number;
|
|
79
|
+
/** Internal: tool_result events that arrived BEFORE their tool_use_start
|
|
80
|
+
* (WebSocket reordering / buffering). Keyed by tool id; applied when the
|
|
81
|
+
* matching tool_use_start lands so the result isn't silently lost. */
|
|
82
|
+
orphanResults?: Record<string, {
|
|
83
|
+
result: string;
|
|
84
|
+
error: boolean;
|
|
85
|
+
}>;
|
|
86
|
+
}
|
|
87
|
+
export declare function initialChatState(): ChatState;
|
|
88
|
+
export declare function reduceStream(state: ChatState, raw: unknown): ChatState;
|
|
89
|
+
/** Append a local user echo (the phone shows its own message immediately). */
|
|
90
|
+
export declare function appendUserMessage(state: ChatState, text: string, attachments?: UserAttachmentSummary[]): ChatState;
|