@ccpocket-base-auth/bridge 1.26.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 +67 -0
- package/dist/archive-store.d.ts +28 -0
- package/dist/archive-store.js +68 -0
- package/dist/archive-store.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +82 -0
- package/dist/cli.js.map +1 -0
- package/dist/codex-process.d.ts +171 -0
- package/dist/codex-process.js +1928 -0
- package/dist/codex-process.js.map +1 -0
- package/dist/debug-trace-store.d.ts +15 -0
- package/dist/debug-trace-store.js +78 -0
- package/dist/debug-trace-store.js.map +1 -0
- package/dist/doctor.d.ts +58 -0
- package/dist/doctor.js +663 -0
- package/dist/doctor.js.map +1 -0
- package/dist/firebase-auth.d.ts +35 -0
- package/dist/firebase-auth.js +132 -0
- package/dist/firebase-auth.js.map +1 -0
- package/dist/gallery-store.d.ts +67 -0
- package/dist/gallery-store.js +333 -0
- package/dist/gallery-store.js.map +1 -0
- package/dist/image-store.d.ts +23 -0
- package/dist/image-store.js +142 -0
- package/dist/image-store.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +191 -0
- package/dist/index.js.map +1 -0
- package/dist/mdns.d.ts +7 -0
- package/dist/mdns.js +49 -0
- package/dist/mdns.js.map +1 -0
- package/dist/parser.d.ts +465 -0
- package/dist/parser.js +251 -0
- package/dist/parser.js.map +1 -0
- package/dist/project-history.d.ts +10 -0
- package/dist/project-history.js +73 -0
- package/dist/project-history.js.map +1 -0
- package/dist/prompt-history-backup.d.ts +15 -0
- package/dist/prompt-history-backup.js +46 -0
- package/dist/prompt-history-backup.js.map +1 -0
- package/dist/proxy.d.ts +15 -0
- package/dist/proxy.js +95 -0
- package/dist/proxy.js.map +1 -0
- package/dist/push-i18n.d.ts +7 -0
- package/dist/push-i18n.js +75 -0
- package/dist/push-i18n.js.map +1 -0
- package/dist/push-relay.d.ts +29 -0
- package/dist/push-relay.js +70 -0
- package/dist/push-relay.js.map +1 -0
- package/dist/recording-store.d.ts +51 -0
- package/dist/recording-store.js +158 -0
- package/dist/recording-store.js.map +1 -0
- package/dist/screenshot.d.ts +28 -0
- package/dist/screenshot.js +98 -0
- package/dist/screenshot.js.map +1 -0
- package/dist/sdk-process.d.ts +180 -0
- package/dist/sdk-process.js +937 -0
- package/dist/sdk-process.js.map +1 -0
- package/dist/session.d.ts +142 -0
- package/dist/session.js +615 -0
- package/dist/session.js.map +1 -0
- package/dist/sessions-index.d.ts +128 -0
- package/dist/sessions-index.js +1767 -0
- package/dist/sessions-index.js.map +1 -0
- package/dist/setup-launchd.d.ts +8 -0
- package/dist/setup-launchd.js +109 -0
- package/dist/setup-launchd.js.map +1 -0
- package/dist/setup-systemd.d.ts +8 -0
- package/dist/setup-systemd.js +118 -0
- package/dist/setup-systemd.js.map +1 -0
- package/dist/startup-info.d.ts +8 -0
- package/dist/startup-info.js +92 -0
- package/dist/startup-info.js.map +1 -0
- package/dist/usage.d.ts +69 -0
- package/dist/usage.js +545 -0
- package/dist/usage.js.map +1 -0
- package/dist/version.d.ts +13 -0
- package/dist/version.js +43 -0
- package/dist/version.js.map +1 -0
- package/dist/websocket.d.ts +127 -0
- package/dist/websocket.js +2482 -0
- package/dist/websocket.js.map +1 -0
- package/dist/worktree-store.d.ts +25 -0
- package/dist/worktree-store.js +59 -0
- package/dist/worktree-store.js.map +1 -0
- package/dist/worktree.d.ts +47 -0
- package/dist/worktree.js +313 -0
- package/dist/worktree.js.map +1 -0
- package/package.json +68 -0
package/README.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# @ccpocket/bridge
|
|
2
|
+
|
|
3
|
+
Bridge server that connects [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code) and [Codex CLI](https://github.com/openai/codex) to mobile devices via WebSocket.
|
|
4
|
+
|
|
5
|
+
This is the server component of [ccpocket](https://github.com/K9i-0/ccpocket) — a mobile client for Claude Code and Codex.
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx @ccpocket/bridge@latest
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
A QR code will appear in your terminal. Scan it with the ccpocket mobile app to connect.
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Run directly (no install needed)
|
|
19
|
+
npx @ccpocket/bridge@latest
|
|
20
|
+
|
|
21
|
+
# Or install globally
|
|
22
|
+
npm install -g @ccpocket/bridge
|
|
23
|
+
ccpocket-bridge
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Configuration
|
|
27
|
+
|
|
28
|
+
| Environment Variable | Default | Description |
|
|
29
|
+
|---------------------|---------|-------------|
|
|
30
|
+
| `BRIDGE_PORT` | `8765` | WebSocket port |
|
|
31
|
+
| `BRIDGE_HOST` | `0.0.0.0` | Bind address |
|
|
32
|
+
| `BRIDGE_API_KEY` | (none) | API key authentication (enabled when set) |
|
|
33
|
+
| `BRIDGE_DEMO_MODE` | (none) | Demo mode: hide Tailscale IPs and API key from QR code / logs |
|
|
34
|
+
| `BRIDGE_RECORDING` | (none) | Enable session recording for debugging (enabled when set) |
|
|
35
|
+
| `HTTPS_PROXY` | (none) | Proxy for outgoing fetch requests (`http://`, `socks5://`) |
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# Example: custom port with API key
|
|
39
|
+
BRIDGE_PORT=9000 BRIDGE_API_KEY=my-secret npx @ccpocket/bridge@latest
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Requirements
|
|
43
|
+
|
|
44
|
+
- Node.js v18+
|
|
45
|
+
- [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code) and/or [Codex CLI](https://github.com/openai/codex)
|
|
46
|
+
|
|
47
|
+
## Health Check
|
|
48
|
+
|
|
49
|
+
Run the built-in doctor command to verify your environment:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npx @ccpocket/bridge@latest doctor
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
It checks Node.js, Git, CLI providers, macOS permissions (Screen Recording, Keychain), network connectivity, and more.
|
|
56
|
+
|
|
57
|
+
## Architecture
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
Mobile App ←WebSocket→ Bridge Server ←stdio→ Claude Code CLI
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The bridge server spawns and manages Claude Code CLI processes, translating WebSocket messages to/from the CLI's stdio interface. It supports multiple concurrent sessions.
|
|
64
|
+
|
|
65
|
+
## License
|
|
66
|
+
|
|
67
|
+
[MIT](../../LICENSE)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface ArchivedSession {
|
|
2
|
+
sessionId: string;
|
|
3
|
+
provider: "claude" | "codex";
|
|
4
|
+
projectPath: string;
|
|
5
|
+
archivedAt: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Manages a persistent set of archived session IDs.
|
|
9
|
+
* Data is stored in `~/.ccpocket/archived-sessions.json`.
|
|
10
|
+
*/
|
|
11
|
+
export declare class ArchiveStore {
|
|
12
|
+
private readonly dirPath;
|
|
13
|
+
private readonly filePath;
|
|
14
|
+
/** In-memory cache of archived session IDs for O(1) lookup. */
|
|
15
|
+
private cache;
|
|
16
|
+
private data;
|
|
17
|
+
constructor();
|
|
18
|
+
/** Initialise the store: create directory if needed and load existing data. */
|
|
19
|
+
init(): Promise<void>;
|
|
20
|
+
/** Archive a session. Idempotent – archiving an already-archived session is a no-op. */
|
|
21
|
+
archive(sessionId: string, provider: "claude" | "codex", projectPath: string): Promise<void>;
|
|
22
|
+
/** Check whether a session is archived. */
|
|
23
|
+
isArchived(sessionId: string): boolean;
|
|
24
|
+
/** Return the full set of archived session IDs (for bulk filtering). */
|
|
25
|
+
archivedIds(): ReadonlySet<string>;
|
|
26
|
+
/** Atomic write: write to temp file, then rename. */
|
|
27
|
+
private save;
|
|
28
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { randomUUID } from "node:crypto";
|
|
5
|
+
/**
|
|
6
|
+
* Manages a persistent set of archived session IDs.
|
|
7
|
+
* Data is stored in `~/.ccpocket/archived-sessions.json`.
|
|
8
|
+
*/
|
|
9
|
+
export class ArchiveStore {
|
|
10
|
+
dirPath;
|
|
11
|
+
filePath;
|
|
12
|
+
/** In-memory cache of archived session IDs for O(1) lookup. */
|
|
13
|
+
cache = new Set();
|
|
14
|
+
data = { version: 1, archivedSessions: [] };
|
|
15
|
+
constructor() {
|
|
16
|
+
this.dirPath = join(homedir(), ".ccpocket");
|
|
17
|
+
this.filePath = join(this.dirPath, "archived-sessions.json");
|
|
18
|
+
}
|
|
19
|
+
/** Initialise the store: create directory if needed and load existing data. */
|
|
20
|
+
async init() {
|
|
21
|
+
await mkdir(this.dirPath, { recursive: true });
|
|
22
|
+
try {
|
|
23
|
+
const raw = await readFile(this.filePath, "utf-8");
|
|
24
|
+
const parsed = JSON.parse(raw);
|
|
25
|
+
if (parsed.version === 1 && Array.isArray(parsed.archivedSessions)) {
|
|
26
|
+
this.data = parsed;
|
|
27
|
+
this.cache = new Set(parsed.archivedSessions.map((s) => s.sessionId));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// File doesn't exist or is corrupted – start fresh.
|
|
32
|
+
this.data = { version: 1, archivedSessions: [] };
|
|
33
|
+
this.cache = new Set();
|
|
34
|
+
}
|
|
35
|
+
console.log(`[archive-store] Loaded ${this.cache.size} archived session(s)`);
|
|
36
|
+
}
|
|
37
|
+
/** Archive a session. Idempotent – archiving an already-archived session is a no-op. */
|
|
38
|
+
async archive(sessionId, provider, projectPath) {
|
|
39
|
+
if (this.cache.has(sessionId))
|
|
40
|
+
return;
|
|
41
|
+
const entry = {
|
|
42
|
+
sessionId,
|
|
43
|
+
provider,
|
|
44
|
+
projectPath,
|
|
45
|
+
archivedAt: new Date().toISOString(),
|
|
46
|
+
};
|
|
47
|
+
this.data.archivedSessions.push(entry);
|
|
48
|
+
this.cache.add(sessionId);
|
|
49
|
+
await this.save();
|
|
50
|
+
console.log(`[archive-store] Archived session ${sessionId}`);
|
|
51
|
+
}
|
|
52
|
+
/** Check whether a session is archived. */
|
|
53
|
+
isArchived(sessionId) {
|
|
54
|
+
return this.cache.has(sessionId);
|
|
55
|
+
}
|
|
56
|
+
/** Return the full set of archived session IDs (for bulk filtering). */
|
|
57
|
+
archivedIds() {
|
|
58
|
+
return this.cache;
|
|
59
|
+
}
|
|
60
|
+
// ---- internal ----
|
|
61
|
+
/** Atomic write: write to temp file, then rename. */
|
|
62
|
+
async save() {
|
|
63
|
+
const tmp = join(this.dirPath, `archived-sessions.${randomUUID()}.tmp`);
|
|
64
|
+
await writeFile(tmp, JSON.stringify(this.data, null, 2), "utf-8");
|
|
65
|
+
await rename(tmp, this.filePath);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=archive-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive-store.js","sourceRoot":"","sources":["../src/archive-store.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { setupProxy } from "./proxy.js";
|
|
3
|
+
import { platform } from "node:os";
|
|
4
|
+
import { startServer } from "./index.js";
|
|
5
|
+
// Configure global fetch proxy before any network calls
|
|
6
|
+
setupProxy();
|
|
7
|
+
const args = process.argv.slice(2);
|
|
8
|
+
// Check for subcommand
|
|
9
|
+
const subcommand = args.find((a) => !a.startsWith("-"));
|
|
10
|
+
function parseFlag(name) {
|
|
11
|
+
const idx = args.indexOf(`--${name}`);
|
|
12
|
+
if (idx === -1 || idx + 1 >= args.length)
|
|
13
|
+
return undefined;
|
|
14
|
+
return args[idx + 1];
|
|
15
|
+
}
|
|
16
|
+
function hasFlag(name) {
|
|
17
|
+
return args.includes(`--${name}`);
|
|
18
|
+
}
|
|
19
|
+
if (subcommand === "doctor") {
|
|
20
|
+
// Doctor subcommand: check environment health
|
|
21
|
+
const jsonOutput = hasFlag("json");
|
|
22
|
+
import("./doctor.js")
|
|
23
|
+
.then(({ runDoctor, printReport }) => runDoctor().then((report) => {
|
|
24
|
+
if (jsonOutput) {
|
|
25
|
+
console.log(JSON.stringify(report));
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
printReport(report);
|
|
29
|
+
}
|
|
30
|
+
process.exit(report.allRequiredPassed ? 0 : 1);
|
|
31
|
+
}))
|
|
32
|
+
.catch((err) => {
|
|
33
|
+
console.error("Doctor failed:", err);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
else if (subcommand === "setup") {
|
|
38
|
+
// Service setup subcommand (platform-specific)
|
|
39
|
+
const opts = {
|
|
40
|
+
port: parseFlag("port"),
|
|
41
|
+
host: parseFlag("host"),
|
|
42
|
+
apiKey: parseFlag("api-key"),
|
|
43
|
+
};
|
|
44
|
+
if (platform() === "darwin") {
|
|
45
|
+
import("./setup-launchd.js")
|
|
46
|
+
.then(({ setupLaunchd, uninstallLaunchd }) => {
|
|
47
|
+
hasFlag("uninstall") ? uninstallLaunchd() : setupLaunchd(opts);
|
|
48
|
+
})
|
|
49
|
+
.catch((err) => {
|
|
50
|
+
console.error("Setup failed:", err);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
else if (platform() === "linux") {
|
|
55
|
+
import("./setup-systemd.js")
|
|
56
|
+
.then(({ setupSystemd, uninstallSystemd }) => {
|
|
57
|
+
hasFlag("uninstall") ? uninstallSystemd() : setupSystemd(opts);
|
|
58
|
+
})
|
|
59
|
+
.catch((err) => {
|
|
60
|
+
console.error("Setup failed:", err);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
console.error(`ERROR: 'setup' is not supported on ${platform()}. Supported: macOS (launchd), Linux (systemd).`);
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
// Server mode: set env vars from CLI flags, then start
|
|
71
|
+
const port = parseFlag("port");
|
|
72
|
+
const host = parseFlag("host");
|
|
73
|
+
const apiKey = parseFlag("api-key");
|
|
74
|
+
if (port)
|
|
75
|
+
process.env.BRIDGE_PORT = port;
|
|
76
|
+
if (host)
|
|
77
|
+
process.env.BRIDGE_HOST = host;
|
|
78
|
+
if (apiKey)
|
|
79
|
+
process.env.BRIDGE_API_KEY = apiKey;
|
|
80
|
+
startServer();
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { EventEmitter } from "node:events";
|
|
2
|
+
import type { ServerMessage, ProcessStatus } from "./parser.js";
|
|
3
|
+
export interface CodexStartOptions {
|
|
4
|
+
threadId?: string;
|
|
5
|
+
approvalPolicy?: "never" | "on-request" | "on-failure" | "untrusted";
|
|
6
|
+
sandboxMode?: "read-only" | "workspace-write" | "danger-full-access";
|
|
7
|
+
model?: string;
|
|
8
|
+
modelReasoningEffort?: "minimal" | "low" | "medium" | "high" | "xhigh";
|
|
9
|
+
networkAccessEnabled?: boolean;
|
|
10
|
+
webSearchMode?: "disabled" | "cached" | "live";
|
|
11
|
+
collaborationMode?: "plan" | "default";
|
|
12
|
+
}
|
|
13
|
+
export interface CodexProcessEvents {
|
|
14
|
+
message: [ServerMessage];
|
|
15
|
+
status: [ProcessStatus];
|
|
16
|
+
exit: [number | null];
|
|
17
|
+
}
|
|
18
|
+
/** Skill metadata returned by the Codex `skills/list` RPC. */
|
|
19
|
+
export interface CodexSkillMetadata {
|
|
20
|
+
name: string;
|
|
21
|
+
path: string;
|
|
22
|
+
description: string;
|
|
23
|
+
shortDescription?: string;
|
|
24
|
+
enabled: boolean;
|
|
25
|
+
scope: string;
|
|
26
|
+
displayName?: string;
|
|
27
|
+
defaultPrompt?: string;
|
|
28
|
+
brandColor?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface CodexThreadSummary {
|
|
31
|
+
id: string;
|
|
32
|
+
preview: string;
|
|
33
|
+
createdAt: number;
|
|
34
|
+
updatedAt: number;
|
|
35
|
+
cwd: string;
|
|
36
|
+
agentNickname: string | null;
|
|
37
|
+
agentRole: string | null;
|
|
38
|
+
gitBranch: string | null;
|
|
39
|
+
name: string | null;
|
|
40
|
+
}
|
|
41
|
+
export declare class CodexProcess extends EventEmitter<CodexProcessEvents> {
|
|
42
|
+
private child;
|
|
43
|
+
private _status;
|
|
44
|
+
private _threadId;
|
|
45
|
+
private _agentNickname;
|
|
46
|
+
private _agentRole;
|
|
47
|
+
private stopped;
|
|
48
|
+
private startModel;
|
|
49
|
+
private inputResolve;
|
|
50
|
+
private pendingTurnId;
|
|
51
|
+
private pendingTurnCompletion;
|
|
52
|
+
private pendingApprovals;
|
|
53
|
+
private pendingUserInputs;
|
|
54
|
+
private lastTokenUsage;
|
|
55
|
+
/** Full skill metadata from the last `skills/list` response. */
|
|
56
|
+
private _skills;
|
|
57
|
+
/** Project path stored for re-fetching skills on `skills/changed`. */
|
|
58
|
+
private _projectPath;
|
|
59
|
+
/** Expose skill metadata so session/websocket can access it. */
|
|
60
|
+
get skills(): CodexSkillMetadata[];
|
|
61
|
+
private rpcSeq;
|
|
62
|
+
private pendingRpc;
|
|
63
|
+
private stdoutBuffer;
|
|
64
|
+
private _approvalPolicy;
|
|
65
|
+
private _collaborationMode;
|
|
66
|
+
private lastPlanItemText;
|
|
67
|
+
private pendingPlanCompletion;
|
|
68
|
+
/** Queued plan execution text when inputResolve wasn't ready at approval time. */
|
|
69
|
+
private _pendingPlanInput;
|
|
70
|
+
get status(): ProcessStatus;
|
|
71
|
+
get isWaitingForInput(): boolean;
|
|
72
|
+
get sessionId(): string | null;
|
|
73
|
+
get agentNickname(): string | null;
|
|
74
|
+
get agentRole(): string | null;
|
|
75
|
+
get isRunning(): boolean;
|
|
76
|
+
get approvalPolicy(): string;
|
|
77
|
+
/**
|
|
78
|
+
* Update approval policy at runtime.
|
|
79
|
+
* Takes effect on the next `turn/start` RPC call.
|
|
80
|
+
*/
|
|
81
|
+
setApprovalPolicy(policy: string): void;
|
|
82
|
+
/**
|
|
83
|
+
* Set collaboration mode ("plan" or "default").
|
|
84
|
+
* Takes effect on the next `turn/start` RPC call.
|
|
85
|
+
*/
|
|
86
|
+
setCollaborationMode(mode: "plan" | "default"): void;
|
|
87
|
+
get collaborationMode(): "plan" | "default";
|
|
88
|
+
/**
|
|
89
|
+
* Rename a thread via the app-server RPC.
|
|
90
|
+
* Sends thread/name/set which persists to ~/.codex/session_index.jsonl.
|
|
91
|
+
*/
|
|
92
|
+
renameThread(name: string): Promise<void>;
|
|
93
|
+
/**
|
|
94
|
+
* Archive a Codex thread via the app-server `thread/archive` RPC.
|
|
95
|
+
* Accepts an explicit threadId so that historical (non-active) sessions
|
|
96
|
+
* can be archived without requiring a running process.
|
|
97
|
+
*/
|
|
98
|
+
archiveThread(threadId: string): Promise<void>;
|
|
99
|
+
listThreads(params?: {
|
|
100
|
+
limit?: number;
|
|
101
|
+
cursor?: string | null;
|
|
102
|
+
cwd?: string;
|
|
103
|
+
searchTerm?: string;
|
|
104
|
+
}): Promise<{
|
|
105
|
+
data: CodexThreadSummary[];
|
|
106
|
+
nextCursor: string | null;
|
|
107
|
+
}>;
|
|
108
|
+
start(projectPath: string, options?: CodexStartOptions): void;
|
|
109
|
+
initializeOnly(projectPath: string): Promise<void>;
|
|
110
|
+
stop(): void;
|
|
111
|
+
private prepareLaunch;
|
|
112
|
+
private launchAppServer;
|
|
113
|
+
interrupt(): void;
|
|
114
|
+
sendInput(text: string): void;
|
|
115
|
+
sendInputWithImages(text: string, images: Array<{
|
|
116
|
+
base64: string;
|
|
117
|
+
mimeType: string;
|
|
118
|
+
}>): void;
|
|
119
|
+
sendInputWithSkill(text: string, skill: {
|
|
120
|
+
name: string;
|
|
121
|
+
path: string;
|
|
122
|
+
}): void;
|
|
123
|
+
approve(toolUseId?: string, _updatedInput?: Record<string, unknown>): void;
|
|
124
|
+
approveAlways(toolUseId?: string): void;
|
|
125
|
+
reject(toolUseId?: string, _message?: string): void;
|
|
126
|
+
answer(toolUseId: string, result: string): void;
|
|
127
|
+
getPendingPermission(toolUseId?: string): {
|
|
128
|
+
toolUseId: string;
|
|
129
|
+
toolName: string;
|
|
130
|
+
input: Record<string, unknown>;
|
|
131
|
+
} | undefined;
|
|
132
|
+
/** Emit a synthetic tool_result so history replay can match it to a permission_request. */
|
|
133
|
+
private emitToolResult;
|
|
134
|
+
private resolvePendingApproval;
|
|
135
|
+
private resolvePendingUserInput;
|
|
136
|
+
/**
|
|
137
|
+
* Plan approved → switch to Default mode and auto-start execution.
|
|
138
|
+
*/
|
|
139
|
+
private handlePlanApproved;
|
|
140
|
+
/**
|
|
141
|
+
* Plan rejected → stay in Plan mode and re-plan with feedback.
|
|
142
|
+
*/
|
|
143
|
+
private handlePlanRejected;
|
|
144
|
+
private bootstrap;
|
|
145
|
+
private initializeRpcConnection;
|
|
146
|
+
/**
|
|
147
|
+
* Fetch skills from Codex app-server via `skills/list` RPC and emit them
|
|
148
|
+
* as a `supported_commands` system message so the Flutter client can display
|
|
149
|
+
* skill entries alongside built-in slash commands.
|
|
150
|
+
*/
|
|
151
|
+
private fetchSkills;
|
|
152
|
+
private runInputLoop;
|
|
153
|
+
private handleStdoutChunk;
|
|
154
|
+
private handleRpcEnvelope;
|
|
155
|
+
private handleRpcResponse;
|
|
156
|
+
private handleServerRequest;
|
|
157
|
+
private handleNotification;
|
|
158
|
+
private handleTurnCompleted;
|
|
159
|
+
private processItemStarted;
|
|
160
|
+
private processItemCompleted;
|
|
161
|
+
private toRpcInput;
|
|
162
|
+
private request;
|
|
163
|
+
private notify;
|
|
164
|
+
private respondToServerRequest;
|
|
165
|
+
private writeEnvelope;
|
|
166
|
+
private rejectAllPending;
|
|
167
|
+
private setStatus;
|
|
168
|
+
private emitMessage;
|
|
169
|
+
private extractToolUseId;
|
|
170
|
+
private handleServerRequestResolved;
|
|
171
|
+
}
|