remodex-cli 1.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/LICENSE +12 -0
- package/README.md +105 -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 +88 -0
- package/dist/cli.js.map +1 -0
- package/dist/codex-process.d.ts +186 -0
- package/dist/codex-process.js +2111 -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 +670 -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/git-assist.d.ts +7 -0
- package/dist/git-assist.js +51 -0
- package/dist/git-assist.js.map +1 -0
- package/dist/git-operations.d.ts +63 -0
- package/dist/git-operations.js +292 -0
- package/dist/git-operations.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 +198 -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 +620 -0
- package/dist/parser.js +423 -0
- package/dist/parser.js.map +1 -0
- package/dist/path-utils.d.ts +4 -0
- package/dist/path-utils.js +34 -0
- package/dist/path-utils.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 +960 -0
- package/dist/sdk-process.js.map +1 -0
- package/dist/session.d.ts +144 -0
- package/dist/session.js +687 -0
- package/dist/session.js.map +1 -0
- package/dist/sessions-index.d.ts +130 -0
- package/dist/sessions-index.js +1817 -0
- package/dist/sessions-index.js.map +1 -0
- package/dist/setup-launchd.d.ts +9 -0
- package/dist/setup-launchd.js +115 -0
- package/dist/setup-launchd.js.map +1 -0
- package/dist/setup-systemd.d.ts +9 -0
- package/dist/setup-systemd.js +122 -0
- package/dist/setup-systemd.js.map +1 -0
- package/dist/startup-info.d.ts +9 -0
- package/dist/startup-info.js +116 -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 +132 -0
- package/dist/websocket.js +3551 -0
- package/dist/websocket.js.map +1 -0
- package/dist/worktree-store.d.ts +26 -0
- package/dist/worktree-store.js +61 -0
- package/dist/worktree-store.js.map +1 -0
- package/dist/worktree.d.ts +47 -0
- package/dist/worktree.js +330 -0
- package/dist/worktree.js.map +1 -0
- package/package.json +62 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
This package is part of the Remodex project.
|
|
2
|
+
|
|
3
|
+
License: SEE LICENSE IN LICENSE
|
|
4
|
+
|
|
5
|
+
The governing license for this package is the repository root LICENSE, including
|
|
6
|
+
the Bridge Redistribution Exception that applies to the Bridge Server component.
|
|
7
|
+
|
|
8
|
+
Repository:
|
|
9
|
+
https://github.com/K9i-0/ccpocket
|
|
10
|
+
|
|
11
|
+
Root license:
|
|
12
|
+
https://github.com/K9i-0/ccpocket/blob/main/LICENSE
|
package/README.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# remodex-cli
|
|
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 [remodex](https://github.com/K9i-0/ccpocket) — a mobile client for Claude Code and Codex.
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx remodex-cli@latest
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
A QR code will appear in your terminal. Scan it with the remodex mobile app to connect.
|
|
14
|
+
|
|
15
|
+
> Warning
|
|
16
|
+
> Versions older than `1.25.0` are deprecated and should not be used for new installs due to potential Anthropic policy concerns around OAuth-based usage.
|
|
17
|
+
> Upgrade to `>=1.25.0` and use `ANTHROPIC_API_KEY` instead of OAuth.
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# Run directly (no install needed)
|
|
23
|
+
npx remodex-cli@latest
|
|
24
|
+
|
|
25
|
+
# Or install globally
|
|
26
|
+
npm install -g remodex-cli
|
|
27
|
+
remodex-cli
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Configuration
|
|
31
|
+
|
|
32
|
+
| Environment Variable | Default | Description |
|
|
33
|
+
|---------------------|---------|-------------|
|
|
34
|
+
| `BRIDGE_PORT` | `8765` | WebSocket port |
|
|
35
|
+
| `BRIDGE_HOST` | `0.0.0.0` | Bind address |
|
|
36
|
+
| `BRIDGE_API_KEY` | (none) | API key authentication (enabled when set) |
|
|
37
|
+
| `BRIDGE_PUBLIC_WS_URL` | (none) | Public `ws://` / `wss://` URL used for startup deep link and QR code |
|
|
38
|
+
| `BRIDGE_DEMO_MODE` | (none) | Demo mode: hide Tailscale IPs and API key from QR code / logs |
|
|
39
|
+
| `BRIDGE_RECORDING` | (none) | Enable session recording for debugging (enabled when set) |
|
|
40
|
+
| `BRIDGE_DISABLE_MDNS` | (none) | Disable mDNS auto-discovery advertisement (enabled when set) |
|
|
41
|
+
| `HTTPS_PROXY` | (none) | Proxy for outgoing fetch requests (`http://`, `socks5://`) |
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# Example: custom port with API key
|
|
45
|
+
BRIDGE_PORT=9000 BRIDGE_API_KEY=my-secret npx remodex-cli@latest
|
|
46
|
+
|
|
47
|
+
# Example: expose Bridge through a reverse proxy / ngrok
|
|
48
|
+
BRIDGE_PUBLIC_WS_URL=wss://example.ngrok-free.app npx remodex-cli@latest
|
|
49
|
+
|
|
50
|
+
# Example: same setting via CLI flag
|
|
51
|
+
remodex-cli --public-ws-url wss://example.ngrok-free.app
|
|
52
|
+
|
|
53
|
+
# Example: disable mDNS advertisement
|
|
54
|
+
BRIDGE_DISABLE_MDNS=1 npx remodex-cli@latest
|
|
55
|
+
# or via CLI flag
|
|
56
|
+
remodex-cli --no-mdns
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
When `BRIDGE_PUBLIC_WS_URL` is set, the startup deep link and terminal QR code
|
|
60
|
+
use that public URL instead of the LAN address. This is useful when the Bridge
|
|
61
|
+
is reachable through a reverse proxy, tunnel, or public domain.
|
|
62
|
+
|
|
63
|
+
Without it, the printed QR code is LAN-oriented by default and typically encodes
|
|
64
|
+
something like `ws://192.168.x.x:8765`.
|
|
65
|
+
|
|
66
|
+
## Requirements
|
|
67
|
+
|
|
68
|
+
- Node.js v18+
|
|
69
|
+
- [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code) and/or [Codex CLI](https://github.com/openai/codex)
|
|
70
|
+
|
|
71
|
+
## Health Check
|
|
72
|
+
|
|
73
|
+
Run the built-in doctor command to verify your environment:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
npx remodex-cli@latest doctor
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
It checks Node.js, Git, CLI providers, macOS permissions (Screen Recording, Keychain), network connectivity, and more.
|
|
80
|
+
|
|
81
|
+
## Architecture
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
Mobile App ←WebSocket→ Bridge Server ←stdio→ Claude Code CLI
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
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.
|
|
88
|
+
|
|
89
|
+
## License
|
|
90
|
+
|
|
91
|
+
This package is governed by the [Remodex license](../../LICENSE).
|
|
92
|
+
|
|
93
|
+
The repository remains under FSL-1.1-MIT, with a specific Bridge Redistribution
|
|
94
|
+
Exception that allows unofficial redistribution of the Bridge Server, including
|
|
95
|
+
environment-specific builds and forks for Windows, WSL, proxy-restricted, or
|
|
96
|
+
other hard-to-validate environments.
|
|
97
|
+
|
|
98
|
+
If you redistribute this package or a modified fork:
|
|
99
|
+
|
|
100
|
+
- do not imply it is official, endorsed, or supported by the Remodex maintainer
|
|
101
|
+
- preserve the license text and clearly state that the software is provided "AS IS"
|
|
102
|
+
- make clear that compliance with Anthropic, OpenAI, network, enterprise, and other third-party terms is the responsibility of the redistributor and end user
|
|
103
|
+
|
|
104
|
+
In short: unofficial Bridge redistributions are permitted for compatibility and
|
|
105
|
+
support purposes, but they remain unsupported and at your own risk.
|
|
@@ -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 `~/.remodex/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 `~/.remodex/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(), ".remodex");
|
|
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,88 @@
|
|
|
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
|
+
publicWsUrl: parseFlag("public-ws-url"),
|
|
44
|
+
};
|
|
45
|
+
if (platform() === "darwin") {
|
|
46
|
+
import("./setup-launchd.js")
|
|
47
|
+
.then(({ setupLaunchd, uninstallLaunchd }) => {
|
|
48
|
+
hasFlag("uninstall") ? uninstallLaunchd() : setupLaunchd(opts);
|
|
49
|
+
})
|
|
50
|
+
.catch((err) => {
|
|
51
|
+
console.error("Setup failed:", err);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
else if (platform() === "linux") {
|
|
56
|
+
import("./setup-systemd.js")
|
|
57
|
+
.then(({ setupSystemd, uninstallSystemd }) => {
|
|
58
|
+
hasFlag("uninstall") ? uninstallSystemd() : setupSystemd(opts);
|
|
59
|
+
})
|
|
60
|
+
.catch((err) => {
|
|
61
|
+
console.error("Setup failed:", err);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
console.error(`ERROR: 'setup' is not supported on ${platform()}. Supported: macOS (launchd), Linux (systemd).`);
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
// Server mode: set env vars from CLI flags, then start
|
|
72
|
+
const port = parseFlag("port");
|
|
73
|
+
const host = parseFlag("host");
|
|
74
|
+
const apiKey = parseFlag("api-key");
|
|
75
|
+
const publicWsUrl = parseFlag("public-ws-url");
|
|
76
|
+
if (port)
|
|
77
|
+
process.env.BRIDGE_PORT = port;
|
|
78
|
+
if (host)
|
|
79
|
+
process.env.BRIDGE_HOST = host;
|
|
80
|
+
if (apiKey)
|
|
81
|
+
process.env.BRIDGE_API_KEY = apiKey;
|
|
82
|
+
if (publicWsUrl)
|
|
83
|
+
process.env.BRIDGE_PUBLIC_WS_URL = publicWsUrl;
|
|
84
|
+
if (hasFlag("no-mdns"))
|
|
85
|
+
process.env.BRIDGE_DISABLE_MDNS = "1";
|
|
86
|
+
startServer();
|
|
87
|
+
}
|
|
88
|
+
//# 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,186 @@
|
|
|
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 function buildCodexSpawnSpec(projectPath: string, platform?: NodeJS.Platform): {
|
|
42
|
+
command: string;
|
|
43
|
+
args: string[];
|
|
44
|
+
options: {
|
|
45
|
+
cwd: string;
|
|
46
|
+
stdio: "pipe";
|
|
47
|
+
env: NodeJS.ProcessEnv;
|
|
48
|
+
windowsVerbatimArguments?: boolean;
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
export declare class CodexProcess extends EventEmitter<CodexProcessEvents> {
|
|
52
|
+
private child;
|
|
53
|
+
private _status;
|
|
54
|
+
private _threadId;
|
|
55
|
+
private _agentNickname;
|
|
56
|
+
private _agentRole;
|
|
57
|
+
private stopped;
|
|
58
|
+
private startModel;
|
|
59
|
+
private inputResolve;
|
|
60
|
+
private pendingTurnId;
|
|
61
|
+
private pendingTurnCompletion;
|
|
62
|
+
private pendingApprovals;
|
|
63
|
+
private pendingUserInputs;
|
|
64
|
+
private lastTokenUsage;
|
|
65
|
+
/** Full skill metadata from the last `skills/list` response. */
|
|
66
|
+
private _skills;
|
|
67
|
+
/** Project path stored for re-fetching skills on `skills/changed`. */
|
|
68
|
+
private _projectPath;
|
|
69
|
+
/** Expose skill metadata so session/websocket can access it. */
|
|
70
|
+
get skills(): CodexSkillMetadata[];
|
|
71
|
+
private rpcSeq;
|
|
72
|
+
private pendingRpc;
|
|
73
|
+
private stdoutBuffer;
|
|
74
|
+
private _approvalPolicy;
|
|
75
|
+
private _collaborationMode;
|
|
76
|
+
private lastPlanItemText;
|
|
77
|
+
/** Last assistant text message — used as `result` in completion notification. */
|
|
78
|
+
private lastResultText;
|
|
79
|
+
private pendingPlanCompletion;
|
|
80
|
+
/** Queued plan execution text when inputResolve wasn't ready at approval time. */
|
|
81
|
+
private _pendingPlanInput;
|
|
82
|
+
private readonly platform;
|
|
83
|
+
constructor(platform?: NodeJS.Platform);
|
|
84
|
+
get status(): ProcessStatus;
|
|
85
|
+
get isWaitingForInput(): boolean;
|
|
86
|
+
private getMessageModel;
|
|
87
|
+
get sessionId(): string | null;
|
|
88
|
+
get agentNickname(): string | null;
|
|
89
|
+
get agentRole(): string | null;
|
|
90
|
+
get isRunning(): boolean;
|
|
91
|
+
get approvalPolicy(): string;
|
|
92
|
+
/**
|
|
93
|
+
* Update approval policy at runtime.
|
|
94
|
+
* Takes effect on the next `turn/start` RPC call.
|
|
95
|
+
*/
|
|
96
|
+
setApprovalPolicy(policy: string): void;
|
|
97
|
+
/**
|
|
98
|
+
* Set collaboration mode ("plan" or "default").
|
|
99
|
+
* Takes effect on the next `turn/start` RPC call.
|
|
100
|
+
*/
|
|
101
|
+
setCollaborationMode(mode: "plan" | "default"): void;
|
|
102
|
+
get collaborationMode(): "plan" | "default";
|
|
103
|
+
/**
|
|
104
|
+
* Rename a thread via the app-server RPC.
|
|
105
|
+
* Sends thread/name/set which persists to ~/.codex/session_index.jsonl.
|
|
106
|
+
*/
|
|
107
|
+
renameThread(name: string): Promise<void>;
|
|
108
|
+
/**
|
|
109
|
+
* Archive a Codex thread via the app-server `thread/archive` RPC.
|
|
110
|
+
* Accepts an explicit threadId so that historical (non-active) sessions
|
|
111
|
+
* can be archived without requiring a running process.
|
|
112
|
+
*/
|
|
113
|
+
archiveThread(threadId: string): Promise<void>;
|
|
114
|
+
listThreads(params?: {
|
|
115
|
+
limit?: number;
|
|
116
|
+
cursor?: string | null;
|
|
117
|
+
cwd?: string;
|
|
118
|
+
searchTerm?: string;
|
|
119
|
+
}): Promise<{
|
|
120
|
+
data: CodexThreadSummary[];
|
|
121
|
+
nextCursor: string | null;
|
|
122
|
+
}>;
|
|
123
|
+
start(projectPath: string, options?: CodexStartOptions): void;
|
|
124
|
+
initializeOnly(projectPath: string): Promise<void>;
|
|
125
|
+
stop(): void;
|
|
126
|
+
private prepareLaunch;
|
|
127
|
+
private launchAppServer;
|
|
128
|
+
interrupt(): void;
|
|
129
|
+
sendInput(text: string): void;
|
|
130
|
+
sendInputWithImages(text: string, images: Array<{
|
|
131
|
+
base64: string;
|
|
132
|
+
mimeType: string;
|
|
133
|
+
}>): void;
|
|
134
|
+
sendInputWithSkill(text: string, skill: {
|
|
135
|
+
name: string;
|
|
136
|
+
path: string;
|
|
137
|
+
}): void;
|
|
138
|
+
approve(toolUseId?: string, _updatedInput?: Record<string, unknown>): void;
|
|
139
|
+
approveAlways(toolUseId?: string): void;
|
|
140
|
+
reject(toolUseId?: string, _message?: string): void;
|
|
141
|
+
answer(toolUseId: string, result: string): void;
|
|
142
|
+
getPendingPermission(toolUseId?: string): {
|
|
143
|
+
toolUseId: string;
|
|
144
|
+
toolName: string;
|
|
145
|
+
input: Record<string, unknown>;
|
|
146
|
+
} | undefined;
|
|
147
|
+
/** Emit a synthetic tool_result so history replay can match it to a permission_request. */
|
|
148
|
+
private emitToolResult;
|
|
149
|
+
private resolvePendingApproval;
|
|
150
|
+
private resolvePendingUserInput;
|
|
151
|
+
/**
|
|
152
|
+
* Plan approved → switch to Default mode and auto-start execution.
|
|
153
|
+
*/
|
|
154
|
+
private handlePlanApproved;
|
|
155
|
+
/**
|
|
156
|
+
* Plan rejected → stay in Plan mode and re-plan with feedback.
|
|
157
|
+
*/
|
|
158
|
+
private handlePlanRejected;
|
|
159
|
+
private bootstrap;
|
|
160
|
+
private initializeRpcConnection;
|
|
161
|
+
/**
|
|
162
|
+
* Fetch skills from Codex app-server via `skills/list` RPC and emit them
|
|
163
|
+
* as a `supported_commands` system message so the Flutter client can display
|
|
164
|
+
* skill entries alongside built-in slash commands.
|
|
165
|
+
*/
|
|
166
|
+
private fetchSkills;
|
|
167
|
+
private runInputLoop;
|
|
168
|
+
private handleStdoutChunk;
|
|
169
|
+
private handleRpcEnvelope;
|
|
170
|
+
private handleRpcResponse;
|
|
171
|
+
private handleServerRequest;
|
|
172
|
+
private handleNotification;
|
|
173
|
+
private handleTurnCompleted;
|
|
174
|
+
private processItemStarted;
|
|
175
|
+
private processItemCompleted;
|
|
176
|
+
private toRpcInput;
|
|
177
|
+
private request;
|
|
178
|
+
private notify;
|
|
179
|
+
private respondToServerRequest;
|
|
180
|
+
private writeEnvelope;
|
|
181
|
+
private rejectAllPending;
|
|
182
|
+
private setStatus;
|
|
183
|
+
private emitMessage;
|
|
184
|
+
private extractToolUseId;
|
|
185
|
+
private handleServerRequestResolved;
|
|
186
|
+
}
|