deepcodex 0.1.0 → 0.1.1
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/.codex-plugin/plugin.json +9 -7
- package/README.md +45 -23
- package/assets/deepcodex.png +0 -0
- package/bin/{opencodex.js → deepcodex.js} +7 -7
- package/config/desktop.json +1 -1
- package/config/worker.json +1 -1
- package/package.json +3 -2
- package/prompts/worker.md +1 -1
- package/scripts/credentials.js +3 -3
- package/scripts/desktop.js +5 -5
- package/scripts/pilot-router.js +1 -1
- package/scripts/pilot.js +3 -3
- package/scripts/worker.js +25 -3
- package/skills/delegate-flash/SKILL.md +4 -4
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "
|
|
3
|
-
"version": "0.1.
|
|
2
|
+
"name": "deepcodex",
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Delegates tasks to native DeepSeek Flash subagents inside Codex through a local router.",
|
|
5
5
|
"author": {
|
|
6
|
-
"name": "
|
|
6
|
+
"name": "DeepCodex"
|
|
7
7
|
},
|
|
8
8
|
"skills": "./skills/",
|
|
9
9
|
"interface": {
|
|
10
|
-
"displayName": "
|
|
10
|
+
"displayName": "DeepCodex",
|
|
11
|
+
"composerIcon": "./assets/deepcodex.png",
|
|
12
|
+
"logo": "./assets/deepcodex.png",
|
|
11
13
|
"shortDescription": "Astra coordinates; DeepSeek Flash executes.",
|
|
12
14
|
"longDescription": "Keeps the coordinator model and connects DeepSeek Flash as a native subagent, with tracking, tools, and results inside Codex.",
|
|
13
|
-
"developerName": "
|
|
15
|
+
"developerName": "DeepCodex",
|
|
14
16
|
"category": "Productivity",
|
|
15
17
|
"capabilities": [
|
|
16
18
|
"Read",
|
|
17
19
|
"Write"
|
|
18
20
|
],
|
|
19
21
|
"defaultPrompt": [
|
|
20
|
-
"Check whether
|
|
21
|
-
"Delegate this implementation to Flash with
|
|
22
|
+
"Check whether DeepCodex is ready.",
|
|
23
|
+
"Delegate this implementation to Flash with DeepCodex."
|
|
22
24
|
]
|
|
23
25
|
}
|
|
24
26
|
}
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# DeepCodex
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
DeepCodex keeps the coordinator on your selected native Codex model and runs
|
|
4
4
|
DeepSeek Flash as an actual Codex subagent through a local loopback router. The
|
|
5
5
|
subagent appears in the normal collaboration tools (`spawn_agent`,
|
|
6
6
|
`followup_task`, `wait_agent`, `interrupt_agent`) under the model name
|
|
@@ -12,9 +12,13 @@ native coordinator model is not replaced.
|
|
|
12
12
|
- macOS. The installer and the LaunchAgent service are macOS-only.
|
|
13
13
|
- Node.js >= 22.15. The worker uses `node:sqlite`, `fetch` and
|
|
14
14
|
`import.meta.resolve`.
|
|
15
|
-
- A Codex CLI on `PATH`
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
- A compatible Codex CLI, either on `PATH` or bundled with Codex Desktop.
|
|
16
|
+
When no CLI is on `PATH`, DeepCodex checks `Codex.app` and `ChatGPT.app`
|
|
17
|
+
under `~/Applications` and `/Applications`, in that order. No separate CLI
|
|
18
|
+
installation is needed when Desktop includes a compatible binary.
|
|
19
|
+
`codex exec` must support `--ignore-user-config`, `--ephemeral`, `--json`
|
|
20
|
+
and `--strict-config`; `deepcodex doctor` verifies this before activation.
|
|
21
|
+
A CLI on `PATH` takes priority, even if it is incompatible.
|
|
18
22
|
- A DeepSeek API key.
|
|
19
23
|
|
|
20
24
|
## Install globally
|
|
@@ -22,24 +26,42 @@ native coordinator model is not replaced.
|
|
|
22
26
|
Once the package is published to npm:
|
|
23
27
|
|
|
24
28
|
```sh
|
|
25
|
-
npm install --global
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
npm install --global deepcodex
|
|
30
|
+
deepcodex configure
|
|
31
|
+
deepcodex doctor
|
|
32
|
+
deepcodex install
|
|
29
33
|
```
|
|
30
34
|
|
|
31
|
-
The global installation adds `
|
|
35
|
+
The global installation adds `deepcodex` to npm's global bin directory, which
|
|
32
36
|
must be on your `PATH`. Run it from any directory; no checkout path is needed.
|
|
33
37
|
|
|
34
38
|
To install the local checkout globally before publication, run these commands
|
|
35
|
-
from the repository, then use the same `
|
|
39
|
+
from the repository, then use the same `deepcodex` commands above:
|
|
36
40
|
|
|
37
41
|
```sh
|
|
38
42
|
pnpm install --frozen-lockfile
|
|
39
43
|
npm install --global .
|
|
40
44
|
```
|
|
41
45
|
|
|
42
|
-
###
|
|
46
|
+
### Upgrading from OpenCodex
|
|
47
|
+
|
|
48
|
+
The npm package, command and plugin are now named `deepcodex`, and the service
|
|
49
|
+
is `com.deepcodex.router`. Existing private paths (`~/.config/opencodex`,
|
|
50
|
+
`~/.local/share/opencodex`) and provider IDs are retained, reusing your saved
|
|
51
|
+
key and backup.
|
|
52
|
+
|
|
53
|
+
If the previous `com.opencodex.router` LaunchAgent is installed, unload it and
|
|
54
|
+
remove its plist before running `deepcodex install` to avoid competing services:
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
launchctl bootout "gui/$(id -u)/com.opencodex.router"
|
|
58
|
+
rm ~/Library/LaunchAgents/com.opencodex.router.plist
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Run `deepcodex doctor` and `deepcodex install` to refresh the runtime; there is
|
|
62
|
+
no need to run `configure` again if your key is already saved.
|
|
63
|
+
|
|
64
|
+
### 1. `deepcodex configure`
|
|
43
65
|
|
|
44
66
|
`configure` asks for the DeepSeek API key with hidden input on the terminal and
|
|
45
67
|
stores it in `~/.config/opencodex/.env`. It creates the directory with mode
|
|
@@ -57,7 +79,7 @@ the file, as does the installed desktop service. Credentials stay outside the
|
|
|
57
79
|
repository. The file permissions restrict other users, but programs running as
|
|
58
80
|
your user can still read it.
|
|
59
81
|
|
|
60
|
-
### 2. `
|
|
82
|
+
### 2. `deepcodex doctor`
|
|
61
83
|
|
|
62
84
|
`doctor` checks the local prerequisites without running inference: that a
|
|
63
85
|
compatible Codex CLI is reachable and that the DeepSeek credential is present.
|
|
@@ -66,7 +88,7 @@ unless the doctor reports `ready`.
|
|
|
66
88
|
Neither `configure` nor `doctor` contacts DeepSeek to validate the key. A `ready`
|
|
67
89
|
result confirms local prerequisites, not provider authentication or account credit.
|
|
68
90
|
|
|
69
|
-
### 3. `
|
|
91
|
+
### 3. `deepcodex install`
|
|
70
92
|
|
|
71
93
|
`install` activates the desktop integration:
|
|
72
94
|
|
|
@@ -74,7 +96,7 @@ result confirms local prerequisites, not provider authentication or account cred
|
|
|
74
96
|
dependency) to `~/.local/share/opencodex/runtime`;
|
|
75
97
|
- writes private state, the model catalog and receipts to
|
|
76
98
|
`~/.config/opencodex/desktop`;
|
|
77
|
-
- installs and starts the `com.
|
|
99
|
+
- installs and starts the `com.deepcodex.router` LaunchAgent, bound only to
|
|
78
100
|
`127.0.0.1:4207`;
|
|
79
101
|
- updates `~/.codex/config.toml` with the local provider, the subagent defaults
|
|
80
102
|
and the generated model catalog, keeping a pre-install backup at
|
|
@@ -90,7 +112,7 @@ that were already open keep the provider and model catalog they started with.
|
|
|
90
112
|
## Plugin skill
|
|
91
113
|
|
|
92
114
|
The delegation skill lives in `skills/delegate-flash/SKILL.md` and is loaded by
|
|
93
|
-
installing the
|
|
115
|
+
installing the DeepCodex plugin through a Codex marketplace. Installing the npm
|
|
94
116
|
package or running the commands above does not install the skill, and this
|
|
95
117
|
checkout is not a marketplace source by itself.
|
|
96
118
|
|
|
@@ -98,13 +120,13 @@ checkout is not a marketplace source by itself.
|
|
|
98
120
|
|
|
99
121
|
| Command | Purpose |
|
|
100
122
|
| --- | --- |
|
|
101
|
-
| `
|
|
102
|
-
| `
|
|
103
|
-
| `
|
|
104
|
-
| `
|
|
105
|
-
| `
|
|
106
|
-
| `
|
|
107
|
-
| `
|
|
123
|
+
| `deepcodex configure` | Prompt for the DeepSeek API key and write `~/.config/opencodex/.env`. |
|
|
124
|
+
| `deepcodex doctor` | Check Codex CLI compatibility and credential presence without inference. |
|
|
125
|
+
| `deepcodex install` | Install the router runtime, the LaunchAgent and the user-level Codex settings. |
|
|
126
|
+
| `deepcodex status` | Query the installed router health endpoint without inference. |
|
|
127
|
+
| `deepcodex run --cwd PATH --task-file PATH [--write]` | Run one bounded isolated worker ticket against DeepSeek. Read-only unless `--write` is given. |
|
|
128
|
+
| `deepcodex pilot` | Run the opt-in live native-delegation test; consumes Codex and DeepSeek usage. |
|
|
129
|
+
| `deepcodex --version`, `deepcodex --help` | Print the package version or the command list. |
|
|
108
130
|
|
|
109
131
|
`run` executes a single ticket and consumes DeepSeek API usage. It takes an
|
|
110
132
|
exclusive per-user lock, so only one worker runs at a time.
|
|
Binary file
|
|
@@ -3,7 +3,7 @@ import { readFileSync } from 'node:fs';
|
|
|
3
3
|
|
|
4
4
|
const args = process.argv.slice(2);
|
|
5
5
|
const command = args.shift();
|
|
6
|
-
const help = `Usage:
|
|
6
|
+
const help = `Usage: deepcodex <command>
|
|
7
7
|
|
|
8
8
|
Commands:
|
|
9
9
|
configure Save the DeepSeek key using a hidden terminal prompt
|
|
@@ -13,11 +13,11 @@ Commands:
|
|
|
13
13
|
run Run an isolated worker ticket (consumes DeepSeek usage)
|
|
14
14
|
pilot Test native delegation (consumes Codex and DeepSeek usage)
|
|
15
15
|
|
|
16
|
-
Requires macOS, Node.js >=22.15 and a compatible Codex CLI.
|
|
17
|
-
Run
|
|
16
|
+
Requires macOS, Node.js >=22.15 and a compatible Codex CLI (PATH or Desktop bundle).
|
|
17
|
+
Run deepcodex configure to save the DeepSeek key in ~/.config/opencodex/.env.
|
|
18
18
|
Installing this npm package does not activate the router or install the skill
|
|
19
19
|
in Codex. Install the plugin through a Codex marketplace to load its skill.
|
|
20
|
-
Use
|
|
20
|
+
Use deepcodex <command> --help for command options.
|
|
21
21
|
`;
|
|
22
22
|
|
|
23
23
|
if (!command || command === '--help' || command === '-h') {
|
|
@@ -33,17 +33,17 @@ if (!command || command === '--help' || command === '-h') {
|
|
|
33
33
|
}
|
|
34
34
|
if (command === 'pilot' && args.length) {
|
|
35
35
|
if (args.length === 1 && ['--help', '-h'].includes(args[0])) {
|
|
36
|
-
console.log('Usage:
|
|
36
|
+
console.log('Usage: deepcodex pilot\nRuns a live native delegation test; consumes Codex and DeepSeek usage.');
|
|
37
37
|
process.exit(0);
|
|
38
38
|
}
|
|
39
|
-
console.error('Usage:
|
|
39
|
+
console.error('Usage: deepcodex pilot (no arguments)');
|
|
40
40
|
process.exit(2);
|
|
41
41
|
}
|
|
42
42
|
try {
|
|
43
43
|
const script = await import(new URL(`../scripts/${scripts[command]}`, import.meta.url));
|
|
44
44
|
process.exitCode = command === 'pilot' ? await script.run() : await script.main([command, ...args]);
|
|
45
45
|
} catch (error) {
|
|
46
|
-
console.error(`
|
|
46
|
+
console.error(`DeepCodex failed: ${error.message}`);
|
|
47
47
|
process.exitCode = 1;
|
|
48
48
|
}
|
|
49
49
|
}
|
package/config/desktop.json
CHANGED
package/config/worker.json
CHANGED
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"sandbox_workspace_write": {"network_access": false}
|
|
40
40
|
},
|
|
41
41
|
"model_metadata": {
|
|
42
|
-
"display_name": "DeepSeek Flash
|
|
42
|
+
"display_name": "DeepSeek Flash",
|
|
43
43
|
"description": "Text worker using the direct DeepSeek API.",
|
|
44
44
|
"default_reasoning_level": "high",
|
|
45
45
|
"supported_reasoning_levels": [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deepcodex",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Native DeepSeek Flash subagents for Codex through a local router.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -17,11 +17,12 @@
|
|
|
17
17
|
],
|
|
18
18
|
"type": "module",
|
|
19
19
|
"bin": {
|
|
20
|
-
"deepcodex": "bin/
|
|
20
|
+
"deepcodex": "bin/deepcodex.js"
|
|
21
21
|
},
|
|
22
22
|
"files": [
|
|
23
23
|
"bin/*.js",
|
|
24
24
|
".codex-plugin/plugin.json",
|
|
25
|
+
"assets/deepcodex.png",
|
|
25
26
|
"skills/delegate-flash/SKILL.md",
|
|
26
27
|
"config/*.json",
|
|
27
28
|
"prompts/worker.md",
|
package/prompts/worker.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
You are the
|
|
1
|
+
You are the DeepCodex worker. Complete only the ticket you received and return
|
|
2
2
|
evidence to the coordinator. Follow the communication language stated in the
|
|
3
3
|
ticket for your reports; keep the language of the code unchanged.
|
|
4
4
|
|
package/scripts/credentials.js
CHANGED
|
@@ -87,16 +87,16 @@ export function saveCredentials(file, name, secret) {
|
|
|
87
87
|
|
|
88
88
|
export async function main(args) {
|
|
89
89
|
if (args.length === 2 && ['--help', '-h'].includes(args[1])) {
|
|
90
|
-
console.log('Usage:
|
|
90
|
+
console.log('Usage: deepcodex configure\nEnter the DeepSeek key in a hidden terminal prompt. Saves a private plaintext file outside the repository.');
|
|
91
91
|
return 0;
|
|
92
92
|
}
|
|
93
|
-
if (args.length !== 1 || args[0] !== 'configure') throw new Error('Usage:
|
|
93
|
+
if (args.length !== 1 || args[0] !== 'configure') throw new Error('Usage: deepcodex configure (no key arguments accepted)');
|
|
94
94
|
const config = loadConfig();
|
|
95
95
|
const name = config.codex.model_providers[config.codex.model_provider].env_key;
|
|
96
96
|
const configured = config.credentials.env_file;
|
|
97
97
|
const file = configured.startsWith('~/') ? path.join(os.homedir(), configured.slice(2)) : configured;
|
|
98
98
|
const secret = await readSecret();
|
|
99
99
|
saveCredentials(file, name, secret);
|
|
100
|
-
console.log('DeepSeek key saved with owner-only permissions. Run
|
|
100
|
+
console.log('DeepSeek key saved with owner-only permissions. Run deepcodex install to activate it or reload an existing router.');
|
|
101
101
|
return 0;
|
|
102
102
|
}
|
package/scripts/desktop.js
CHANGED
|
@@ -103,7 +103,7 @@ export async function install() {
|
|
|
103
103
|
const env = workerEnvironment(process.env);
|
|
104
104
|
loadCredentials(env, original);
|
|
105
105
|
const diagnosis = doctor(original, env);
|
|
106
|
-
if (diagnosis.status !== 'ready') throw new Error(
|
|
106
|
+
if (diagnosis.status !== 'ready') throw new Error(`DeepCodex prerequisites are not ready: ${diagnosis.errors.join(' ')}`);
|
|
107
107
|
const configPath = path.join(env.CODEX_HOME || path.join(os.homedir(), '.codex'), 'config.toml');
|
|
108
108
|
const before = fs.readFileSync(configPath, 'utf8');
|
|
109
109
|
const parsed = parseToml(before);
|
|
@@ -135,7 +135,7 @@ export async function install() {
|
|
|
135
135
|
'': { model_provider: 'opencodex', model_catalog_json: path.join(STATE, 'models.json') },
|
|
136
136
|
agents: { enabled: true, default_subagent_model: child.slug, default_subagent_reasoning_effort: 'high' },
|
|
137
137
|
features: { multi_agent: true, multi_agent_v2: true },
|
|
138
|
-
'model_providers.opencodex': { name: '
|
|
138
|
+
'model_providers.opencodex': { name: 'DeepCodex', base_url: `http://127.0.0.1:${config.port}`, wire_api: 'responses',
|
|
139
139
|
requires_openai_auth: true, supports_websockets: false, request_max_retries: 0, stream_max_retries: 0, stream_idle_timeout_ms: config.request_timeout_ms },
|
|
140
140
|
'model_providers.opencodex.http_headers': { 'x-opencodex-pilot': capability },
|
|
141
141
|
};
|
|
@@ -153,7 +153,7 @@ export async function install() {
|
|
|
153
153
|
const domain = `gui/${process.getuid()}`;
|
|
154
154
|
spawnSync('launchctl', ['bootout', `${domain}/${label}`]);
|
|
155
155
|
const bootstrap = spawnSync('launchctl', ['bootstrap', domain, plist]);
|
|
156
|
-
if (bootstrap.error || bootstrap.status !== 0) throw new Error('Cannot start
|
|
156
|
+
if (bootstrap.error || bootstrap.status !== 0) throw new Error('Cannot start DeepCodex LaunchAgent');
|
|
157
157
|
const deadline = Date.now() + config.startup_timeout_seconds * 1000;
|
|
158
158
|
let report;
|
|
159
159
|
while (!report) {
|
|
@@ -168,13 +168,13 @@ export async function install() {
|
|
|
168
168
|
}
|
|
169
169
|
if (fs.readFileSync(configPath, 'utf8') !== before) throw new Error('Codex config changed during installation; proposed config was not applied');
|
|
170
170
|
privateWrite(configPath, updated);
|
|
171
|
-
console.log(JSON.stringify({ ...report, service: label, port: config.port, cwd: runtime, owner: '
|
|
171
|
+
console.log(JSON.stringify({ ...report, service: label, port: config.port, cwd: runtime, owner: 'DeepCodex LaunchAgent',
|
|
172
172
|
native_models: nativeModels.length, subagent_model: child.slug, backup: path.join(STATE, 'config.before.toml'), restart_desktop_required: true }));
|
|
173
173
|
}
|
|
174
174
|
|
|
175
175
|
export async function main(args = process.argv.slice(2)) {
|
|
176
176
|
if (args.includes('--help') || args.includes('-h')) {
|
|
177
|
-
console.log('Usage:
|
|
177
|
+
console.log('Usage: deepcodex <install|status>\nActivate or inspect the local macOS Desktop router.');
|
|
178
178
|
return 0;
|
|
179
179
|
}
|
|
180
180
|
if (args.length !== 1 || !['install', 'serve', 'status'].includes(args[0])) throw new Error('Expected install, serve or status');
|
package/scripts/pilot-router.js
CHANGED
|
@@ -223,7 +223,7 @@ export async function startPilot(config, deepseekKey, capability) {
|
|
|
223
223
|
return;
|
|
224
224
|
}
|
|
225
225
|
receipt({ route: 'error', message: String(error.message).replaceAll(deepseekKey, '[REDACTED]').replaceAll(capability, '[REDACTED]') });
|
|
226
|
-
if (!response.headersSent) response.writeHead(502, { 'content-type': 'application/json' }).end(JSON.stringify({ error: { message: '
|
|
226
|
+
if (!response.headersSent) response.writeHead(502, { 'content-type': 'application/json' }).end(JSON.stringify({ error: { message: 'DeepCodex request failed; inspect local receipts.' } }));
|
|
227
227
|
else response.destroy();
|
|
228
228
|
} finally { clearTimeout(timer); }
|
|
229
229
|
});
|
package/scripts/pilot.js
CHANGED
|
@@ -120,7 +120,7 @@ export async function run() {
|
|
|
120
120
|
const sourceEnv = workerEnvironment(process.env);
|
|
121
121
|
loadCredentials(sourceEnv, workerConfig);
|
|
122
122
|
const diagnosis = doctor(workerConfig, sourceEnv);
|
|
123
|
-
if (diagnosis.status !== 'ready') throw new Error('
|
|
123
|
+
if (diagnosis.status !== 'ready') throw new Error('DeepCodex doctor is not ready');
|
|
124
124
|
const authSource = authFile(sourceEnv);
|
|
125
125
|
if (!statSync(authSource, { throwIfNoEntry: false })?.isFile()) {
|
|
126
126
|
throw new Error('Pilot requires the existing Codex auth.json login');
|
|
@@ -165,7 +165,7 @@ export async function run() {
|
|
|
165
165
|
{ env, cwd: workspace, stdio: ['pipe', 'pipe', routerErrors], detached: true });
|
|
166
166
|
router.stdin.end(JSON.stringify({ config, capability }));
|
|
167
167
|
const ready = await readRouterReadiness(router, config.startup_timeout_seconds * 1000, signals.signal);
|
|
168
|
-
emit({ event: 'pilot.router_started', ...ready, cwd: workspace, owner: '
|
|
168
|
+
emit({ event: 'pilot.router_started', ...ready, cwd: workspace, owner: 'DeepCodex isolated pilot',
|
|
169
169
|
artifacts: runDir });
|
|
170
170
|
const values = { ...workerConfig.codex };
|
|
171
171
|
Object.assign(values, { model: config.parent_model, model_provider: 'opencodex-pilot',
|
|
@@ -175,7 +175,7 @@ export async function run() {
|
|
|
175
175
|
values.features = { ...values.features, multi_agent: true, multi_agent_v2: true,
|
|
176
176
|
enable_request_compression: false };
|
|
177
177
|
values.model_providers = { 'opencodex-pilot': {
|
|
178
|
-
name: '
|
|
178
|
+
name: 'DeepCodex isolated pilot',
|
|
179
179
|
base_url: `http://127.0.0.1:${ready.port}`,
|
|
180
180
|
wire_api: 'responses',
|
|
181
181
|
requires_openai_auth: true,
|
package/scripts/worker.js
CHANGED
|
@@ -99,8 +99,23 @@ export function redact(value, secret) {
|
|
|
99
99
|
return value;
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
|
|
102
|
+
// Desktop bundles the CLI but does not necessarily expose it on PATH.
|
|
103
|
+
export function resolveCodex(env, { platform = process.platform, applicationDirs = [
|
|
104
|
+
path.join(env.HOME || os.homedir(), 'Applications'), '/Applications',
|
|
105
|
+
] } = {}) {
|
|
103
106
|
const binary = which('codex', env.PATH);
|
|
107
|
+
if (binary || platform !== 'darwin') return binary;
|
|
108
|
+
for (const directory of applicationDirs) {
|
|
109
|
+
for (const app of ['Codex.app', 'ChatGPT.app']) {
|
|
110
|
+
const bundled = which('codex', path.join(directory, app, 'Contents', 'Resources'));
|
|
111
|
+
if (bundled) return bundled;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return undefined;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function doctor(config, env, discoveryOptions) {
|
|
118
|
+
const binary = resolveCodex(env, discoveryOptions);
|
|
104
119
|
const report = { status: 'ready', codex: binary ?? null, api_key_present: Boolean(env.DEEPSEEK_API_KEY) };
|
|
105
120
|
if (binary) {
|
|
106
121
|
const timeout = config.limits.version_timeout_seconds * 1000;
|
|
@@ -110,7 +125,14 @@ export function doctor(config, env) {
|
|
|
110
125
|
report.compatible_cli = version.status === 0 && help.status === 0
|
|
111
126
|
&& REQUIRED_CLI_FLAGS.every(flag => help.stdout.includes(flag));
|
|
112
127
|
}
|
|
113
|
-
|
|
128
|
+
const errors = [];
|
|
129
|
+
if (!binary) errors.push('Codex CLI not found on PATH or in Codex.app/ChatGPT.app under ~/Applications or /Applications. Install Codex Desktop or add a compatible codex CLI to PATH.');
|
|
130
|
+
else if (!report.compatible_cli) errors.push(`Codex CLI at ${binary} is incompatible; required exec flags: ${REQUIRED_CLI_FLAGS.join(', ')}. Update Codex Desktop or the CLI on PATH.`);
|
|
131
|
+
if (!report.api_key_present) errors.push('DeepSeek API key is missing. Run deepcodex configure.');
|
|
132
|
+
if (errors.length) {
|
|
133
|
+
report.status = 'not_ready';
|
|
134
|
+
report.errors = errors;
|
|
135
|
+
}
|
|
114
136
|
return report;
|
|
115
137
|
}
|
|
116
138
|
|
|
@@ -147,7 +169,7 @@ export async function workerLock() {
|
|
|
147
169
|
database.exec('BEGIN EXCLUSIVE');
|
|
148
170
|
} catch (error) {
|
|
149
171
|
database.close();
|
|
150
|
-
if (error.errcode === SQLITE_BUSY) throw new Error('Another
|
|
172
|
+
if (error.errcode === SQLITE_BUSY) throw new Error('Another DeepCodex worker is running; wait for it or cancel that run');
|
|
151
173
|
throw error;
|
|
152
174
|
}
|
|
153
175
|
let closed = false;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: delegate-flash
|
|
3
|
-
description: Delegate bounded coding tasks to native DeepSeek Flash subagents in Codex through
|
|
3
|
+
description: Delegate bounded coding tasks to native DeepSeek Flash subagents in Codex through DeepCodex. Use when DeepCodex or Flash delegation is requested, or when diagnosing the Desktop integration.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# DeepCodex
|
|
7
7
|
|
|
8
8
|
Keep the coordinator on the user's selected native model. DeepSeek Flash runs as
|
|
9
|
-
an actual Codex subagent through the local
|
|
9
|
+
an actual Codex subagent through the local DeepCodex router. Use the native
|
|
10
10
|
collaboration tools for spawning, follow-ups, waiting, and interruption; the
|
|
11
11
|
normal delegation path does not launch a separate `codex exec` worker.
|
|
12
12
|
|
|
@@ -42,7 +42,7 @@ is in `config/desktop.json`, shared transport defaults in `config/pilot.json`,
|
|
|
42
42
|
and the DeepSeek model and credential path in `config/worker.json`.
|
|
43
43
|
|
|
44
44
|
Run `node <plugin>/scripts/desktop.js status` to check the local service without
|
|
45
|
-
inference. The service is `com.
|
|
45
|
+
inference. The service is `com.deepcodex.router`, bound only to loopback. Private
|
|
46
46
|
state and bounded metadata receipts live in `~/.config/opencodex/desktop`.
|
|
47
47
|
Receipts contain routing and tool names, not prompts, tool arguments or tokens.
|
|
48
48
|
Do not print `state.json`, provider headers, credential files or full user config.
|