codex-task 0.2.3 → 0.2.5

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/server.js ADDED
@@ -0,0 +1,503 @@
1
+ import { randomUUID, timingSafeEqual } from "node:crypto";
2
+ import { createReadStream, existsSync, lstatSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
3
+ import { createServer } from "node:http";
4
+ import { basename, join } from "node:path";
5
+ import { dispatch } from "./api.js";
6
+ import { asCodexTaskError } from "./errors.js";
7
+ import { ensureDir } from "./fs-utils.js";
8
+ import { appPaths } from "./paths.js";
9
+ function backendForRequest(request) {
10
+ if (request.kind === "task" || request.kind === "resume")
11
+ return "sdk";
12
+ return request.options.backend ?? "direct";
13
+ }
14
+ function writeJson(response, status, value) {
15
+ response.writeHead(status, {
16
+ "content-type": "application/json; charset=utf-8",
17
+ "cache-control": "no-store",
18
+ });
19
+ response.end(`${JSON.stringify(value)}\n`);
20
+ }
21
+ function authorized(request, token) {
22
+ if (!token)
23
+ return true;
24
+ const header = request.headers.authorization;
25
+ if (!header?.startsWith("Bearer "))
26
+ return false;
27
+ const supplied = Buffer.from(header.slice("Bearer ".length));
28
+ const expected = Buffer.from(token);
29
+ return supplied.length === expected.length && timingSafeEqual(supplied, expected);
30
+ }
31
+ function isLoopbackHost(host) {
32
+ const normalized = host.toLowerCase().replace(/^\[|\]$/g, "");
33
+ return normalized === "localhost" || normalized === "::1" || /^127(?:\.\d{1,3}){3}$/.test(normalized);
34
+ }
35
+ async function readJson(request, maxBodyBytes) {
36
+ const chunks = [];
37
+ let bytes = 0;
38
+ for await (const chunk of request) {
39
+ const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
40
+ bytes += buffer.length;
41
+ if (bytes > maxBodyBytes)
42
+ throw new Error("REQUEST_TOO_LARGE");
43
+ chunks.push(buffer);
44
+ }
45
+ const text = Buffer.concat(chunks).toString("utf8");
46
+ const value = JSON.parse(text);
47
+ if (!value || typeof value !== "object" || Array.isArray(value))
48
+ throw new Error("INVALID_JSON_BODY");
49
+ return value;
50
+ }
51
+ function remotePrompt(body) {
52
+ const parts = [];
53
+ if (typeof body["prompt"] === "string" && body["prompt"].trim())
54
+ parts.push(body["prompt"].trim());
55
+ const promptFiles = body["promptFiles"];
56
+ if (promptFiles !== undefined) {
57
+ if (!Array.isArray(promptFiles) || promptFiles.length > 20)
58
+ throw new Error("INVALID_PROMPT_FILES");
59
+ for (const item of promptFiles) {
60
+ if (!item || typeof item !== "object" || Array.isArray(item))
61
+ throw new Error("INVALID_PROMPT_FILES");
62
+ const record = item;
63
+ const name = typeof record["name"] === "string" ? basename(record["name"]).trim() : "";
64
+ const content = typeof record["content"] === "string" ? record["content"].trim() : "";
65
+ if (!name || !content || name.length > 200)
66
+ throw new Error("INVALID_PROMPT_FILES");
67
+ parts.push(`--- BEGIN PROMPT FILE: ${name} ---\n${content}\n--- END PROMPT FILE ---`);
68
+ }
69
+ }
70
+ if (parts.length === 0)
71
+ throw new Error("MISSING_PROMPT");
72
+ return parts.join("\n\n");
73
+ }
74
+ const REASONING_EFFORTS = new Set(["none", "low", "medium", "high", "xhigh", "max", "ultra"]);
75
+ function remoteCommonOptions(body) {
76
+ const reasoning = typeof body["reasoning"] === "string" && REASONING_EFFORTS.has(body["reasoning"])
77
+ ? body["reasoning"]
78
+ : undefined;
79
+ const timeoutMs = typeof body["timeoutMs"] === "number" && Number.isFinite(body["timeoutMs"]) && body["timeoutMs"] > 0
80
+ ? body["timeoutMs"]
81
+ : undefined;
82
+ const retries = typeof body["retries"] === "number" && Number.isInteger(body["retries"]) && body["retries"] >= 0 && body["retries"] <= 10
83
+ ? body["retries"]
84
+ : undefined;
85
+ const schema = body["schema"];
86
+ const outputSchema = schema && typeof schema === "object" && !Array.isArray(schema)
87
+ ? schema
88
+ : undefined;
89
+ return {
90
+ ...(typeof body["model"] === "string" && body["model"].trim() ? { model: body["model"].trim() } : {}),
91
+ ...(reasoning ? { reasoning } : {}),
92
+ ...(typeof body["instructions"] === "string" && body["instructions"].trim() ? { instructions: body["instructions"].trim() } : {}),
93
+ ...(outputSchema ? { outputSchema } : {}),
94
+ ...(timeoutMs ? { timeoutMs } : {}),
95
+ ...(retries !== undefined ? { retries } : {}),
96
+ };
97
+ }
98
+ const IMAGE_EXTENSION = {
99
+ "image/png": ".png",
100
+ "image/jpeg": ".jpg",
101
+ "image/webp": ".webp",
102
+ "image/gif": ".gif",
103
+ };
104
+ function decodeBase64(value) {
105
+ const compact = value.replace(/\s/g, "");
106
+ if (!compact || !/^[A-Za-z0-9+/]*={0,2}$/.test(compact) || compact.length % 4 !== 0) {
107
+ throw new Error("INVALID_IMAGE_DATA");
108
+ }
109
+ return Buffer.from(compact, "base64");
110
+ }
111
+ function materializeImages(jobId, body) {
112
+ const images = body["images"];
113
+ if (images === undefined)
114
+ return { paths: [] };
115
+ if (!Array.isArray(images) || images.length > 5)
116
+ throw new Error("INVALID_IMAGES");
117
+ const uploadDir = join(appPaths().tempDir, "server", jobId);
118
+ const inputDir = join(uploadDir, "inputs");
119
+ const decoded = [];
120
+ let totalBytes = 0;
121
+ for (const item of images) {
122
+ if (!item || typeof item !== "object" || Array.isArray(item))
123
+ throw new Error("INVALID_IMAGES");
124
+ const record = item;
125
+ const mimeType = typeof record["mimeType"] === "string" ? record["mimeType"].toLowerCase() : "";
126
+ const extension = IMAGE_EXTENSION[mimeType];
127
+ if (!extension || typeof record["dataBase64"] !== "string")
128
+ throw new Error("INVALID_IMAGES");
129
+ const bytes = decodeBase64(record["dataBase64"]);
130
+ if (bytes.length > 20 * 1024 * 1024)
131
+ throw new Error("IMAGE_TOO_LARGE");
132
+ totalBytes += bytes.length;
133
+ decoded.push({ bytes, extension });
134
+ }
135
+ if (totalBytes > 50 * 1024 * 1024)
136
+ throw new Error("IMAGES_TOO_LARGE");
137
+ ensureDir(inputDir);
138
+ const paths = decoded.map((image, index) => {
139
+ const path = join(inputDir, `image-${index + 1}${image.extension}`);
140
+ writeFileSync(path, image.bytes, { mode: 0o600 });
141
+ return path;
142
+ });
143
+ return { paths, uploadDir };
144
+ }
145
+ function removeExpiredUploadDirectories(ttlMs) {
146
+ const root = join(appPaths().tempDir, "server");
147
+ if (!existsSync(root))
148
+ return;
149
+ const cutoff = Date.now() - ttlMs;
150
+ for (const entry of readdirSync(root, { withFileTypes: true })) {
151
+ if (!entry.isDirectory() || !/^[0-9a-f]{8}-[0-9a-f-]{27}$/i.test(entry.name))
152
+ continue;
153
+ const path = join(root, entry.name);
154
+ try {
155
+ if (lstatSync(path).mtimeMs < cutoff)
156
+ rmSync(path, { recursive: true, force: true });
157
+ }
158
+ catch {
159
+ // A concurrent cleanup or permissions issue must not prevent service startup.
160
+ }
161
+ }
162
+ }
163
+ function publicResult(job, result) {
164
+ return {
165
+ ...result,
166
+ artifacts: result.artifacts.map(({ path: _path, ...artifact }, index) => ({
167
+ ...artifact,
168
+ downloadUrl: `/v1/jobs/${job.jobId}/artifacts/${index}`,
169
+ })),
170
+ };
171
+ }
172
+ function jobSnapshot(job) {
173
+ return {
174
+ jobId: job.jobId,
175
+ kind: job.kind,
176
+ status: job.status,
177
+ createdAt: job.createdAt,
178
+ updatedAt: job.updatedAt,
179
+ ...(job.result ? { result: publicResult(job, job.result) } : {}),
180
+ };
181
+ }
182
+ export async function startCodexTaskServer(options = {}) {
183
+ const host = options.host ?? "127.0.0.1";
184
+ const port = options.port ?? 7777;
185
+ if (!isLoopbackHost(host) && !options.token?.trim()) {
186
+ throw new Error("A non-loopback listener requires a Service Token");
187
+ }
188
+ const run = options.run ?? dispatch;
189
+ const maxBodyBytes = options.maxBodyBytes ?? 72 * 1024 * 1024;
190
+ const jobTtlMs = options.jobTtlMs ?? 24 * 60 * 60 * 1000;
191
+ if (!Number.isFinite(jobTtlMs) || jobTtlMs < 1)
192
+ throw new Error("jobTtlMs must be positive");
193
+ removeExpiredUploadDirectories(jobTtlMs);
194
+ const maxConcurrency = options.maxConcurrency ?? 2;
195
+ if (!Number.isInteger(maxConcurrency) || maxConcurrency < 1 || maxConcurrency > 16) {
196
+ throw new Error("maxConcurrency must be an integer from 1 to 16");
197
+ }
198
+ const jobs = new Map();
199
+ const pending = [];
200
+ let active = 0;
201
+ const drain = () => {
202
+ while (active < maxConcurrency && pending.length > 0) {
203
+ const next = pending.shift();
204
+ if (!next)
205
+ return;
206
+ const { job, request: taskRequest } = next;
207
+ active += 1;
208
+ job.status = "running";
209
+ job.updatedAt = new Date().toISOString();
210
+ void run(taskRequest)
211
+ .then((result) => {
212
+ job.status = result.status;
213
+ job.result = result;
214
+ job.updatedAt = new Date().toISOString();
215
+ })
216
+ .catch((error) => {
217
+ const normalized = asCodexTaskError(error);
218
+ job.status = "failed";
219
+ job.result = {
220
+ status: "failed",
221
+ taskId: randomUUID(),
222
+ backend: backendForRequest(taskRequest),
223
+ artifacts: [],
224
+ error: {
225
+ code: normalized.code,
226
+ message: normalized.message,
227
+ retryable: normalized.retryable,
228
+ },
229
+ };
230
+ job.updatedAt = new Date().toISOString();
231
+ })
232
+ .finally(() => {
233
+ if (job.uploadDir)
234
+ rmSync(job.uploadDir, { recursive: true, force: true });
235
+ active -= 1;
236
+ const expiry = setTimeout(() => jobs.delete(job.jobId), jobTtlMs);
237
+ expiry.unref();
238
+ drain();
239
+ });
240
+ }
241
+ };
242
+ const execute = (job, taskRequest) => {
243
+ pending.push({ job, request: taskRequest });
244
+ queueMicrotask(drain);
245
+ };
246
+ const server = createServer((request, response) => {
247
+ void (async () => {
248
+ const url = new URL(request.url ?? "/", `http://${request.headers.host ?? "localhost"}`);
249
+ if (request.method === "GET" && url.pathname === "/healthz") {
250
+ writeJson(response, 200, { ok: true, service: "codex-task" });
251
+ return;
252
+ }
253
+ if (url.pathname.startsWith("/v1/") && !authorized(request, options.token)) {
254
+ writeJson(response, 401, {
255
+ error: { code: "UNAUTHORIZED", message: "A valid Bearer token is required" },
256
+ });
257
+ return;
258
+ }
259
+ if (request.method === "POST" && url.pathname === "/v1/text") {
260
+ let body;
261
+ let uploadDir;
262
+ try {
263
+ body = await readJson(request, maxBodyBytes);
264
+ }
265
+ catch (error) {
266
+ const tooLarge = error instanceof Error && error.message === "REQUEST_TOO_LARGE";
267
+ writeJson(response, tooLarge ? 413 : 400, {
268
+ error: {
269
+ code: tooLarge ? "REQUEST_TOO_LARGE" : "INVALID_REQUEST",
270
+ message: tooLarge ? "Request body exceeds the configured limit" : "Request body must be valid JSON",
271
+ },
272
+ });
273
+ return;
274
+ }
275
+ try {
276
+ const now = new Date().toISOString();
277
+ const job = {
278
+ jobId: randomUUID(),
279
+ kind: "text",
280
+ status: "queued",
281
+ createdAt: now,
282
+ updatedAt: now,
283
+ };
284
+ const uploaded = materializeImages(job.jobId, body);
285
+ uploadDir = uploaded.uploadDir;
286
+ job.uploadDir = uploadDir;
287
+ const backend = body["backend"] === "sdk" ? "sdk" : "direct";
288
+ const taskRequest = {
289
+ kind: "text",
290
+ options: {
291
+ ...remoteCommonOptions(body),
292
+ prompt: remotePrompt(body),
293
+ imagePaths: uploaded.paths,
294
+ backend,
295
+ ...(typeof body["workingDirectory"] === "string" ? { workingDirectory: body["workingDirectory"] } : {}),
296
+ },
297
+ };
298
+ jobs.set(job.jobId, job);
299
+ execute(job, taskRequest);
300
+ writeJson(response, 202, {
301
+ jobId: job.jobId,
302
+ status: "queued",
303
+ statusUrl: `/v1/jobs/${job.jobId}`,
304
+ });
305
+ }
306
+ catch (error) {
307
+ if (uploadDir)
308
+ rmSync(uploadDir, { recursive: true, force: true });
309
+ const message = error instanceof Error ? error.message : "INVALID_REQUEST";
310
+ writeJson(response, 400, {
311
+ error: { code: message, message: "Text request is invalid" },
312
+ });
313
+ }
314
+ return;
315
+ }
316
+ if (request.method === "POST" && url.pathname === "/v1/image") {
317
+ let body;
318
+ try {
319
+ body = await readJson(request, maxBodyBytes);
320
+ const now = new Date().toISOString();
321
+ const job = {
322
+ jobId: randomUUID(),
323
+ kind: "image",
324
+ status: "queued",
325
+ createdAt: now,
326
+ updatedAt: now,
327
+ };
328
+ const uploaded = materializeImages(job.jobId, body);
329
+ job.uploadDir = uploaded.uploadDir;
330
+ const taskRequest = {
331
+ kind: "image",
332
+ options: {
333
+ ...remoteCommonOptions(body),
334
+ prompt: remotePrompt(body),
335
+ imagePaths: uploaded.paths,
336
+ backend: body["backend"] === "sdk" ? "sdk" : "direct",
337
+ temporary: true,
338
+ ...(typeof body["workingDirectory"] === "string" ? { workingDirectory: body["workingDirectory"] } : {}),
339
+ ...(typeof body["count"] === "number" ? { count: body["count"] } : {}),
340
+ ...(typeof body["concurrency"] === "number" ? { concurrency: body["concurrency"] } : {}),
341
+ ...(typeof body["size"] === "string" ? { size: body["size"] } : {}),
342
+ ...(typeof body["quality"] === "string" ? { quality: body["quality"] } : {}),
343
+ ...(typeof body["background"] === "string" ? { background: body["background"] } : {}),
344
+ },
345
+ };
346
+ jobs.set(job.jobId, job);
347
+ execute(job, taskRequest);
348
+ writeJson(response, 202, {
349
+ jobId: job.jobId,
350
+ status: "queued",
351
+ statusUrl: `/v1/jobs/${job.jobId}`,
352
+ });
353
+ }
354
+ catch (error) {
355
+ const message = error instanceof Error ? error.message : "INVALID_REQUEST";
356
+ writeJson(response, message === "REQUEST_TOO_LARGE" ? 413 : 400, {
357
+ error: { code: message, message: "Image request is invalid" },
358
+ });
359
+ }
360
+ return;
361
+ }
362
+ if (request.method === "POST" && url.pathname === "/v1/task") {
363
+ try {
364
+ const body = await readJson(request, maxBodyBytes);
365
+ const now = new Date().toISOString();
366
+ const job = {
367
+ jobId: randomUUID(),
368
+ kind: "task",
369
+ status: "queued",
370
+ createdAt: now,
371
+ updatedAt: now,
372
+ };
373
+ const uploaded = materializeImages(job.jobId, body);
374
+ job.uploadDir = uploaded.uploadDir;
375
+ const sandbox = body["sandboxMode"];
376
+ const sandboxMode = sandbox === "read-only" || sandbox === "workspace-write" || sandbox === "danger-full-access"
377
+ ? sandbox
378
+ : undefined;
379
+ const taskRequest = {
380
+ kind: "task",
381
+ options: {
382
+ ...remoteCommonOptions(body),
383
+ prompt: remotePrompt(body),
384
+ imagePaths: uploaded.paths,
385
+ backend: "sdk",
386
+ ...(typeof body["workingDirectory"] === "string" ? { workingDirectory: body["workingDirectory"] } : {}),
387
+ ...(sandboxMode ? { sandboxMode } : {}),
388
+ ...(typeof body["networkAccess"] === "boolean" ? { networkAccess: body["networkAccess"] } : {}),
389
+ ...(typeof body["noFollowup"] === "boolean" ? { noFollowup: body["noFollowup"] } : {}),
390
+ },
391
+ };
392
+ jobs.set(job.jobId, job);
393
+ execute(job, taskRequest);
394
+ writeJson(response, 202, {
395
+ jobId: job.jobId,
396
+ status: "queued",
397
+ statusUrl: `/v1/jobs/${job.jobId}`,
398
+ });
399
+ }
400
+ catch (error) {
401
+ const message = error instanceof Error ? error.message : "INVALID_REQUEST";
402
+ writeJson(response, message === "REQUEST_TOO_LARGE" ? 413 : 400, {
403
+ error: { code: message, message: "Workspace task request is invalid" },
404
+ });
405
+ }
406
+ return;
407
+ }
408
+ const resumeMatch = request.method === "POST"
409
+ ? url.pathname.match(/^\/v1\/tasks\/([0-9a-f-]{36})\/resume$/i)
410
+ : null;
411
+ if (resumeMatch) {
412
+ try {
413
+ const body = await readJson(request, maxBodyBytes);
414
+ const now = new Date().toISOString();
415
+ const job = {
416
+ jobId: randomUUID(),
417
+ kind: "resume",
418
+ status: "queued",
419
+ createdAt: now,
420
+ updatedAt: now,
421
+ };
422
+ const uploaded = materializeImages(job.jobId, body);
423
+ job.uploadDir = uploaded.uploadDir;
424
+ const taskRequest = {
425
+ kind: "resume",
426
+ options: {
427
+ ...remoteCommonOptions(body),
428
+ taskId: resumeMatch[1] ?? "",
429
+ answer: remotePrompt(body),
430
+ imagePaths: uploaded.paths,
431
+ ...(typeof body["noFollowup"] === "boolean" ? { noFollowup: body["noFollowup"] } : {}),
432
+ },
433
+ };
434
+ jobs.set(job.jobId, job);
435
+ execute(job, taskRequest);
436
+ writeJson(response, 202, {
437
+ jobId: job.jobId,
438
+ status: "queued",
439
+ statusUrl: `/v1/jobs/${job.jobId}`,
440
+ });
441
+ }
442
+ catch (error) {
443
+ const message = error instanceof Error ? error.message : "INVALID_REQUEST";
444
+ writeJson(response, message === "REQUEST_TOO_LARGE" ? 413 : 400, {
445
+ error: { code: message, message: "Resume request is invalid" },
446
+ });
447
+ }
448
+ return;
449
+ }
450
+ const jobMatch = request.method === "GET" ? url.pathname.match(/^\/v1\/jobs\/([0-9a-f-]{36})$/i) : null;
451
+ if (jobMatch) {
452
+ const job = jobs.get(jobMatch[1] ?? "");
453
+ if (!job) {
454
+ writeJson(response, 404, { error: { code: "JOB_NOT_FOUND", message: "Remote job not found" } });
455
+ return;
456
+ }
457
+ writeJson(response, 200, jobSnapshot(job));
458
+ return;
459
+ }
460
+ const artifactMatch = request.method === "GET"
461
+ ? url.pathname.match(/^\/v1\/jobs\/([0-9a-f-]{36})\/artifacts\/(\d+)$/i)
462
+ : null;
463
+ if (artifactMatch) {
464
+ const job = jobs.get(artifactMatch[1] ?? "");
465
+ const index = Number(artifactMatch[2]);
466
+ const artifact = job?.result?.artifacts[index];
467
+ if (!artifact || !existsSync(artifact.path)) {
468
+ writeJson(response, 404, { error: { code: "ARTIFACT_NOT_FOUND", message: "Artifact not found" } });
469
+ return;
470
+ }
471
+ const stat = statSync(artifact.path);
472
+ response.writeHead(200, {
473
+ "content-type": artifact.mimeType ?? "application/octet-stream",
474
+ "content-length": stat.size,
475
+ "content-disposition": `attachment; filename="${basename(artifact.path).replace(/[^a-zA-Z0-9._-]/g, "-")}"`,
476
+ "cache-control": "private, no-store",
477
+ });
478
+ createReadStream(artifact.path).pipe(response);
479
+ return;
480
+ }
481
+ writeJson(response, 404, { error: { code: "NOT_FOUND", message: "Route not found" } });
482
+ })().catch((error) => {
483
+ const normalized = asCodexTaskError(error);
484
+ writeJson(response, 500, { error: { code: normalized.code, message: normalized.message } });
485
+ });
486
+ });
487
+ await new Promise((resolve, reject) => {
488
+ const onError = (error) => reject(error);
489
+ server.once("error", onError);
490
+ server.listen(port, host, () => {
491
+ server.off("error", onError);
492
+ resolve();
493
+ });
494
+ });
495
+ const address = server.address();
496
+ return {
497
+ host,
498
+ port: address.port,
499
+ url: `http://${host.includes(":") ? `[${host}]` : host}:${address.port}`,
500
+ close: () => new Promise((resolve, reject) => server.close((error) => (error ? reject(error) : resolve()))),
501
+ };
502
+ }
503
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ # CodexTask 手机端示例
2
+
3
+ 这里的 Android Kotlin 和 iOS Swift 客户端调用已经运行的 `codex-task serve`。推荐连接可信局域网、Tailscale/WireGuard,或带 HTTPS 的反向代理。
4
+
5
+ 不要把生产 Service Token 提交到 Git,也不要硬编码到公开 App。示例构造器接收 token,私有 App 可以从 Android Keystore、iOS Keychain、受管配置或用户输入中读取。
6
+
7
+ ## 完整示例流程
8
+
9
+ 两个 `MealWorkflow` 都会实际串起四类任务:
10
+
11
+ 1. `POST /v1/image`:根据文字和 `style.md` 生成健身营养餐。
12
+ 2. 轮询 job,读取 `result.artifacts[0].downloadUrl`,携带同一 token 下载图片。
13
+ 3. `POST /v1/text`:把图片和 JSON Schema 一起上传,做图生文营养分析。
14
+ 4. `POST /v1/task`:把营养 JSON、参考图片和服务器上的项目目录交给 Codex SDK 修改。
15
+ 5. 如果返回 `needs_input`,使用 `result.taskId` 调用 `POST /v1/tasks/:taskId/resume`。
16
+
17
+ 所有提交先返回 `202`、`jobId` 和 `statusUrl`。客户端轮询 `GET statusUrl`,直到 `completed`、`needs_input`、`failed` 或 `cancelled`。这种设计不会让手机保持一个可能持续数十分钟的 HTTP 请求。
18
+
19
+ 命名 prompt 文档格式为 `{name, content}`;图片格式为 `{name, mimeType, dataBase64}`。text、image、task 和 resume 都能组合文本、多份文档与多张图片。
20
+
21
+ ## Android
22
+
23
+ 文件:
24
+
25
+ - [`android/CodexTaskClient.kt`](./android/CodexTaskClient.kt):OkHttp + coroutines 客户端,包含四类提交、轮询与 artifact 下载。
26
+ - [`android/MealWorkflow.kt`](./android/MealWorkflow.kt):完整营养餐流程。
27
+
28
+ Gradle 依赖:
29
+
30
+ ```kotlin
31
+ implementation("com.squareup.okhttp3:okhttp:4.12.0")
32
+ implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2")
33
+ ```
34
+
35
+ 从 ViewModel 或协程中调用:
36
+
37
+ ```kotlin
38
+ val client = CodexTaskClient("http://192.168.1.50:7777", tokenFromKeystore)
39
+ val result = runMealWorkflow(client, "/absolute/server/path/to/meal-app")
40
+ ```
41
+
42
+ Android 默认阻止明文 HTTP。生产环境应使用 HTTPS 或 VPN;仅在可信局域网开发时,才通过范围收窄的 Network Security Config 放行指定主机,不要全局允许明文流量。
43
+
44
+ ## iOS
45
+
46
+ 文件:
47
+
48
+ - [`ios/CodexTaskClient.swift`](./ios/CodexTaskClient.swift):Foundation `URLSession` async/await 客户端。
49
+ - [`ios/MealWorkflow.swift`](./ios/MealWorkflow.swift):与 Android 相同的完整流程。
50
+
51
+ 调用示例:
52
+
53
+ ```swift
54
+ let client = CodexTaskClient(baseURL: URL(string: "http://192.168.1.50:7777")!, token: tokenFromKeychain)
55
+ let result = try await runMealWorkflow(client: client, serverProjectPath: "/absolute/server/path/to/meal-app")
56
+ ```
57
+
58
+ iOS App Transport Security 默认阻止明文 HTTP。生产环境应使用 HTTPS 或 VPN;局域网调试时只为目标域名配置 ATS 开发例外。
59
+
60
+ ## 服务地址
61
+
62
+ `0.0.0.0` 是电脑的监听地址,不是手机可以访问的目标地址。App 应配置电脑可达的地址,例如:
63
+
64
+ ```text
65
+ http://192.168.1.50:7777
66
+ https://codex-task.example.internal
67
+ ```
68
+
69
+ 平台安装脚本打印的 token 通过 `Authorization: Bearer <token>` 发送。持有 token 的手机可以触发服务器上该用户权限范围内的 CodexTask;尤其要谨慎开放 `/v1/task`。