@youdie006/prodex 0.5.0 → 0.6.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 +1 -1
- package/dist/chatgpt-browser.d.ts +3 -3
- package/dist/chatgpt-browser.js +37 -17
- package/dist/chatgpt-browser.js.map +1 -1
- package/dist/cli-args.d.ts +52 -0
- package/dist/cli-args.js +332 -0
- package/dist/cli-args.js.map +1 -0
- package/dist/cli-help.d.ts +20 -0
- package/dist/cli-help.js +259 -0
- package/dist/cli-help.js.map +1 -0
- package/dist/cli.js +3 -587
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { execFile } from "node:child_process";
|
|
3
|
-
import { realpathSync
|
|
3
|
+
import { realpathSync } from "node:fs";
|
|
4
4
|
import { lstat, mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
5
|
-
import { createRequire } from "node:module";
|
|
6
5
|
import { tmpdir } from "node:os";
|
|
7
6
|
import path from "node:path";
|
|
8
7
|
import { fileURLToPath } from "node:url";
|
|
@@ -17,36 +16,14 @@ import { startHttpMcpServer } from "./http-mcp.js";
|
|
|
17
16
|
import { createMcpToolHandlers } from "./mcp-tools.js";
|
|
18
17
|
import { runMcpServer } from "./mcp.js";
|
|
19
18
|
import { readVerifiedUtf8File, writeVerifiedUtf8File } from "./safe-file.js";
|
|
20
|
-
import { ReceiptKindSchema, TaskStatusSchema } from "./schema.js";
|
|
21
19
|
import { BridgeStore, MAX_FETCHABLE_RESULT_ARTIFACT_BYTES } from "./store.js";
|
|
20
|
+
import { ASK_PRO_BOOLEAN_FLAGS, ASK_PRO_PREVIEW_VALUE_FLAGS, ASK_PRO_SELECTION_CLEAR_FLAGS, ASK_PRO_SELECTION_DEFAULT_FLAGS, ASK_PRO_VALUE_FLAGS, assertHelpRequestArgs, assertNoExtraArgs, assertOnlyOptions, findHelpFlagIndexBeforePromptDelimiter, formatCliCommand, formatSourceCliOption, hasAskProDryRunMode, hasAskProMode, hasAskProSendMode, isHelpSubcommand, parseAskProArgs, readFlag, readPortFlag, readPositionalsWithOptions, readPositiveNumberFlag, readReceiptKindFlag, readRepeatedFlag, readSessionStatusFlag, readTaskStatusFlag, resolveCwdFlag, resolveExistingPathFlag, resolveOptionalFileFlag, shellQuote, unknownSubcommandError, unknownTopLevelCommandError } from "./cli-args.js";
|
|
21
|
+
import { CLI_VERSION, printClaudeHelp, printDoctorHelp, printHelp, printInitHelp, printMcpHelp, printOnboardHelp, printProBrowserHelp, printProHelp, printProjectHelp, printReceiptsHelp, printReleaseHelp, printResultsHelp, printSessionsHelp, printSetupHelp, printStartHelp, printStatusHelp, printTasksHelp, printTunnelHelp, printTunnelUrlHelp } from "./cli-help.js";
|
|
22
22
|
const execFileAsync = promisify(execFile);
|
|
23
|
-
const requirePackageJson = createRequire(import.meta.url);
|
|
24
|
-
const packageJson = requirePackageJson("../package.json");
|
|
25
23
|
const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
26
|
-
const CLI_VERSION = packageJson.version ?? "0.0.0";
|
|
27
24
|
const RESERVED_PACKAGE_NAMES = new Set(["node_modules", "favicon.ico"]);
|
|
28
25
|
const PRO_BROWSER_SMOKE_TOKEN = "PRODEX_PRO_SMOKE_OK";
|
|
29
26
|
const TOKEN_BEARING_MCP_URL_AUTHORITY_WARNING = "Token-bearing MCP URL authorizes all enabled bridge tools, including repo_read_file, repo_search, repo_write_file_dry_run, repo_write_file_apply, and repo_stage_reviewed_paths. Paste it only into your own trusted private MCP client.";
|
|
30
|
-
const TOP_LEVEL_COMMANDS = [
|
|
31
|
-
"help",
|
|
32
|
-
"version",
|
|
33
|
-
"init",
|
|
34
|
-
"setup",
|
|
35
|
-
"start",
|
|
36
|
-
"status",
|
|
37
|
-
"tunnel",
|
|
38
|
-
"doctor",
|
|
39
|
-
"onboard",
|
|
40
|
-
"project",
|
|
41
|
-
"claude",
|
|
42
|
-
"tasks",
|
|
43
|
-
"results",
|
|
44
|
-
"receipts",
|
|
45
|
-
"sessions",
|
|
46
|
-
"pro",
|
|
47
|
-
"release",
|
|
48
|
-
"mcp"
|
|
49
|
-
];
|
|
50
27
|
const DOCTOR_REQUIRED_MCP_TOOLS = [
|
|
51
28
|
"bridge_create_task",
|
|
52
29
|
"bridge_list_tasks",
|
|
@@ -1192,222 +1169,6 @@ function defaultIo() {
|
|
|
1192
1169
|
stderr: (line) => console.error(line)
|
|
1193
1170
|
};
|
|
1194
1171
|
}
|
|
1195
|
-
function printHelp(stdout) {
|
|
1196
|
-
stdout(`prodex v${CLI_VERSION}
|
|
1197
|
-
|
|
1198
|
-
Commands:
|
|
1199
|
-
prodex --version
|
|
1200
|
-
prodex init [--cwd /absolute/path/to/repo]
|
|
1201
|
-
prodex doctor [--cwd /absolute/path/to/repo] [--source-cli /absolute/path/to/dist/cli.js]
|
|
1202
|
-
prodex setup [--cwd /absolute/path/to/repo] [--host 127.0.0.1] [--port 8787] [--token-ttl-hours <hours>] [--model Pro] [--pro-mode 기본|확장] [--effort 즉시|중간|높음|"매우 높음"] [--project "name"] [--clear-model|--clear-pro-mode|--clear-effort|--clear-project] [--interactive]
|
|
1203
|
-
prodex start [--cwd /absolute/path/to/repo] [--source-cli /absolute/path/to/dist/cli.js]
|
|
1204
|
-
prodex status [--cwd /absolute/path/to/repo] [--source-cli /absolute/path/to/dist/cli.js] [--show-token] [--url-only] [--unsafe-show-non-expiring-token]
|
|
1205
|
-
prodex tunnel url [--cwd /absolute/path/to/repo] [--source-cli /absolute/path/to/dist/cli.js] --public-url https://... [--show-token] [--url-only]
|
|
1206
|
-
prodex release status [--cwd /absolute/path/to/repo] [--source-cli /absolute/path/to/dist/cli.js]
|
|
1207
|
-
prodex release pack [--cwd /absolute/path/to/repo] [--source-cli /absolute/path/to/dist/cli.js] --pack-destination /absolute/path [--keep-workdir]
|
|
1208
|
-
prodex onboard [--cwd /absolute/path/to/repo] [--source-cli /absolute/path/to/dist/cli.js]
|
|
1209
|
-
prodex project prompt [--cwd /absolute/path/to/repo] [--source-cli /absolute/path/to/dist/cli.js]
|
|
1210
|
-
prodex claude prompt [--cwd /absolute/path/to/repo] [--source-cli /absolute/path/to/dist/cli.js]
|
|
1211
|
-
prodex claude config [--cwd /absolute/path/to/repo] [--source-cli /absolute/path/to/dist/cli.js]
|
|
1212
|
-
prodex pro ask [--dry-run] [--cwd /absolute/path/to/repo] [--file path] "prompt" # dry-run preview
|
|
1213
|
-
prodex pro browser login [--cwd /absolute/path/to/repo] [--dry-run] [--source-cli /absolute/path/to/dist/cli.js] [--profile-dir path] [--port 9333] [--url https://chatgpt.com/...] [--launch-timeout-ms 5000] # preview/open visible browser login
|
|
1214
|
-
prodex pro browser help [--source-cli /absolute/path/to/dist/cli.js]
|
|
1215
|
-
prodex pro browser check [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo] [--port 9333] [--timeout-ms 1500]
|
|
1216
|
-
prodex pro browser smoke [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo] [--port 9333] [--timeout-ms 90000]
|
|
1217
|
-
prodex pro browser models [--source-cli /absolute/path/to/dist/cli.js] [--port 9333] [--timeout-ms 15000] # read-only list of model menu options
|
|
1218
|
-
prodex pro browser ask [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo] [--port 9333] [--timeout-ms 90000] [--target-url url --confirm-target] [--file path] [--model Pro] [--pro-mode 기본|확장] [--effort 즉시|중간|높음|"매우 높음"] [--project "name" | --project-new "name"] "prompt" # explicit visible-browser send
|
|
1219
|
-
prodex pro latest [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo]
|
|
1220
|
-
prodex pro list [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo]
|
|
1221
|
-
prodex pro show <task-id|latest> [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo]
|
|
1222
|
-
prodex tasks create [--cwd /absolute/path/to/repo] --title "Title" --prompt "Prompt"
|
|
1223
|
-
prodex tasks list [--status new|claimed|done|blocked] [--cwd /absolute/path/to/repo]
|
|
1224
|
-
prodex tasks show <task-id|latest> [--cwd /absolute/path/to/repo]
|
|
1225
|
-
prodex tasks claim <task-id> [--cwd /absolute/path/to/repo] [--by codex]
|
|
1226
|
-
prodex tasks complete <task-id> [--cwd /absolute/path/to/repo] --summary "Summary" [--command "npm test"] [--artifact .bridge/artifacts/results/name.md=text]
|
|
1227
|
-
prodex tasks block <task-id> [--cwd /absolute/path/to/repo] --summary "Summary" [--code code] [--next-step "Next step"] [--retryable]
|
|
1228
|
-
prodex results show <task-id|latest> [--cwd /absolute/path/to/repo]
|
|
1229
|
-
prodex results artifact <task-id|latest> [artifact-path] [--cwd /absolute/path/to/repo]
|
|
1230
|
-
prodex results reseal <task-id|latest> --confirm-current-result [--cwd /absolute/path/to/repo]
|
|
1231
|
-
prodex receipts list [--kind kind] [--task-id task-id] [--cwd /absolute/path/to/repo]
|
|
1232
|
-
prodex receipts show <receipt-id|latest> [--cwd /absolute/path/to/repo]
|
|
1233
|
-
prodex receipts rotate-key [--cwd /absolute/path/to/repo]
|
|
1234
|
-
prodex sessions list [--status preview|running|done|blocked] [--cwd /absolute/path/to/repo]
|
|
1235
|
-
prodex sessions show <session-id|latest> [--cwd /absolute/path/to/repo]
|
|
1236
|
-
prodex mcp [--cwd /absolute/path/to/repo]`);
|
|
1237
|
-
}
|
|
1238
|
-
function printInitHelp(stdout) {
|
|
1239
|
-
stdout(`prodex init
|
|
1240
|
-
|
|
1241
|
-
Commands:
|
|
1242
|
-
prodex init [--cwd /absolute/path/to/repo]
|
|
1243
|
-
|
|
1244
|
-
Initialize the local .bridge receipt ledger and bridge .gitignore entries.`);
|
|
1245
|
-
}
|
|
1246
|
-
function printSetupHelp(stdout) {
|
|
1247
|
-
stdout(`prodex setup
|
|
1248
|
-
|
|
1249
|
-
Commands:
|
|
1250
|
-
prodex setup [--cwd /absolute/path/to/repo] [--host 127.0.0.1] [--port 8787] [--token-ttl-hours <hours>] [--model Pro] [--pro-mode 기본|확장] [--effort 즉시|중간|높음|"매우 높음"] [--project "name"] [--clear-model|--clear-pro-mode|--clear-effort|--clear-project] [--interactive]
|
|
1251
|
-
|
|
1252
|
-
Save a loopback-only HTTP MCP profile in .bridge/config.local.json. Use --token-ttl-hours before tunnels or ChatGPT Project use.
|
|
1253
|
-
|
|
1254
|
-
Optional visible-browser send defaults (applied by \`pro browser ask\` when the matching per-ask flag is omitted):
|
|
1255
|
-
--model Composer model to pick by its exact menu label (verified: Pro)
|
|
1256
|
-
--pro-mode Pro sub-mode: 기본 (standard) or 확장 (extended)
|
|
1257
|
-
--effort Reasoning effort: 즉시 / 중간 / 높음 / 매우 높음 (English aliases: instant/medium/high/max); picking one deselects Pro
|
|
1258
|
-
--project Sidebar project to enter before sending
|
|
1259
|
-
Clear a saved default with --clear-model / --clear-pro-mode / --clear-effort / --clear-project.
|
|
1260
|
-
--pro-mode and --effort are different model axes and cannot be combined. View saved defaults with \`prodex status\`.`);
|
|
1261
|
-
}
|
|
1262
|
-
function printStartHelp(stdout) {
|
|
1263
|
-
stdout(`prodex start
|
|
1264
|
-
|
|
1265
|
-
Commands:
|
|
1266
|
-
prodex start [--cwd /absolute/path/to/repo] [--source-cli /absolute/path/to/dist/cli.js]
|
|
1267
|
-
|
|
1268
|
-
Start the local loopback HTTP MCP server from the saved setup profile.`);
|
|
1269
|
-
}
|
|
1270
|
-
function printStatusHelp(stdout) {
|
|
1271
|
-
stdout(`prodex status
|
|
1272
|
-
|
|
1273
|
-
Commands:
|
|
1274
|
-
prodex status [--cwd /absolute/path/to/repo] [--source-cli /absolute/path/to/dist/cli.js] [--show-token] [--url-only] [--unsafe-show-non-expiring-token]
|
|
1275
|
-
|
|
1276
|
-
Show the saved local MCP URL with tokens redacted by default.`);
|
|
1277
|
-
}
|
|
1278
|
-
function printTunnelHelp(stdout) {
|
|
1279
|
-
stdout(`prodex tunnel
|
|
1280
|
-
|
|
1281
|
-
Commands:
|
|
1282
|
-
prodex tunnel url [--cwd /absolute/path/to/repo] [--source-cli /absolute/path/to/dist/cli.js] --public-url https://... [--show-token] [--url-only]
|
|
1283
|
-
|
|
1284
|
-
Format a public tunnel MCP URL from an existing local setup. This command does not create a tunnel.`);
|
|
1285
|
-
}
|
|
1286
|
-
function printTunnelUrlHelp(stdout) {
|
|
1287
|
-
stdout(`prodex tunnel url
|
|
1288
|
-
|
|
1289
|
-
Commands:
|
|
1290
|
-
prodex tunnel url [--cwd /absolute/path/to/repo] [--source-cli /absolute/path/to/dist/cli.js] --public-url https://... [--show-token] [--url-only]
|
|
1291
|
-
|
|
1292
|
-
This command does not create a tunnel. It only formats your supplied public URL with the saved short-lived MCP token.`);
|
|
1293
|
-
}
|
|
1294
|
-
function printDoctorHelp(stdout) {
|
|
1295
|
-
stdout(`prodex doctor
|
|
1296
|
-
|
|
1297
|
-
Commands:
|
|
1298
|
-
prodex doctor [--cwd /absolute/path/to/repo] [--source-cli /absolute/path/to/dist/cli.js]
|
|
1299
|
-
|
|
1300
|
-
Run local bridge, MCP, write/apply/stage, and HTTP MCP smoke checks without opening ChatGPT.`);
|
|
1301
|
-
}
|
|
1302
|
-
function printOnboardHelp(stdout) {
|
|
1303
|
-
stdout(`prodex onboard
|
|
1304
|
-
|
|
1305
|
-
Commands:
|
|
1306
|
-
prodex onboard [--cwd /absolute/path/to/repo] [--source-cli /absolute/path/to/dist/cli.js]
|
|
1307
|
-
|
|
1308
|
-
Print a local-first setup guide for Codex, ChatGPT Projects, Claude, and visible-browser Pro consults.`);
|
|
1309
|
-
}
|
|
1310
|
-
function printMcpHelp(stdout) {
|
|
1311
|
-
stdout(`prodex mcp
|
|
1312
|
-
|
|
1313
|
-
Commands:
|
|
1314
|
-
prodex mcp [--cwd /absolute/path/to/repo]
|
|
1315
|
-
|
|
1316
|
-
Run the stdio MCP server for local clients such as Claude. This does not reveal HTTP MCP URL tokens.`);
|
|
1317
|
-
}
|
|
1318
|
-
function printReleaseHelp(stdout) {
|
|
1319
|
-
stdout(`prodex release
|
|
1320
|
-
|
|
1321
|
-
Commands:
|
|
1322
|
-
prodex release status [--cwd /absolute/path/to/repo] [--source-cli /absolute/path/to/dist/cli.js]
|
|
1323
|
-
prodex release pack [--cwd /absolute/path/to/repo] [--source-cli /absolute/path/to/dist/cli.js] --pack-destination /absolute/path [--keep-workdir]
|
|
1324
|
-
|
|
1325
|
-
Release commands are local checks and package preparation helpers; they do not publish or push.`);
|
|
1326
|
-
}
|
|
1327
|
-
function printProHelp(stdout) {
|
|
1328
|
-
stdout(`prodex pro
|
|
1329
|
-
|
|
1330
|
-
Commands:
|
|
1331
|
-
prodex pro ask [--dry-run] [--cwd /absolute/path/to/repo] [--file path] "prompt"
|
|
1332
|
-
prodex pro browser help [--source-cli /absolute/path/to/dist/cli.js]
|
|
1333
|
-
prodex pro browser login [--cwd /absolute/path/to/repo] [--dry-run] [--source-cli /absolute/path/to/dist/cli.js] [--launch-timeout-ms 5000]
|
|
1334
|
-
prodex pro browser check [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo]
|
|
1335
|
-
prodex pro browser smoke [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo]
|
|
1336
|
-
prodex pro browser models [--source-cli /absolute/path/to/dist/cli.js]
|
|
1337
|
-
prodex pro browser ask [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo] [--target-url url --confirm-target] [--file path] [--model Pro] [--pro-mode 기본|확장] [--effort 즉시|중간|높음|"매우 높음"] [--project "name" | --project-new "name"] "prompt"
|
|
1338
|
-
prodex pro latest [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo]
|
|
1339
|
-
prodex pro list [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo]
|
|
1340
|
-
prodex pro show <task-id|latest> [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo]
|
|
1341
|
-
|
|
1342
|
-
Use \`prodex pro ask\` for dry-run/manual previews.
|
|
1343
|
-
Use \`prodex pro browser ask\` only when you want an explicit visible-browser send.
|
|
1344
|
-
Model/project selection (visible-browser send):
|
|
1345
|
-
--model "label" Pick the composer model by its exact menu label (verified: Pro). Submenu models (e.g. GPT-5.5 variants) are rejected for now.
|
|
1346
|
-
--pro-mode 기본 | 확장 Pro sub-mode (only when the model is Pro); 확장 raises the default timeout to 300000 ms
|
|
1347
|
-
--effort 즉시|중간|높음|매우 높음 Reasoning effort (aliases: instant/medium/high/max); picking one deselects Pro
|
|
1348
|
-
--project "name" Enter an existing sidebar project first (cannot combine with --target-url)
|
|
1349
|
-
Labels match the Korean ChatGPT UI; run \`prodex pro browser models\` to list what your account shows.
|
|
1350
|
-
Persist defaults with \`prodex setup --model/--pro-mode/--effort/--project\`; clear them with setup --clear-model/--clear-pro-mode/--clear-effort/--clear-project.
|
|
1351
|
-
(Creating a new project from the CLI is planned; for now create it in ChatGPT and pass --project.)`);
|
|
1352
|
-
}
|
|
1353
|
-
function printProjectHelp(stdout) {
|
|
1354
|
-
stdout(`prodex project
|
|
1355
|
-
|
|
1356
|
-
Commands:
|
|
1357
|
-
prodex project prompt [--cwd /absolute/path/to/repo] [--source-cli /absolute/path/to/dist/cli.js]
|
|
1358
|
-
|
|
1359
|
-
Print a ChatGPT Project MCP verification prompt. The prompt asks for read/task handoff verification only.`);
|
|
1360
|
-
}
|
|
1361
|
-
function printClaudeHelp(stdout) {
|
|
1362
|
-
stdout(`prodex claude
|
|
1363
|
-
|
|
1364
|
-
Commands:
|
|
1365
|
-
prodex claude prompt [--cwd /absolute/path/to/repo] [--source-cli /absolute/path/to/dist/cli.js]
|
|
1366
|
-
prodex claude config [--cwd /absolute/path/to/repo] [--source-cli /absolute/path/to/dist/cli.js]
|
|
1367
|
-
|
|
1368
|
-
Print Claude MCP setup and verification helpers. These commands do not start MCP or reveal HTTP tokens.`);
|
|
1369
|
-
}
|
|
1370
|
-
function printTasksHelp(stdout) {
|
|
1371
|
-
stdout(`prodex tasks
|
|
1372
|
-
|
|
1373
|
-
Commands:
|
|
1374
|
-
prodex tasks create [--cwd /absolute/path/to/repo] --title "Title" --prompt "Prompt"
|
|
1375
|
-
prodex tasks list [--status new|claimed|done|blocked] [--cwd /absolute/path/to/repo]
|
|
1376
|
-
prodex tasks show <task-id|latest> [--cwd /absolute/path/to/repo]
|
|
1377
|
-
prodex tasks claim <task-id> [--cwd /absolute/path/to/repo] [--by codex]
|
|
1378
|
-
prodex tasks complete <task-id> [--cwd /absolute/path/to/repo] --summary "Summary" [--command "npm test"] [--artifact .bridge/artifacts/results/name.md=text]
|
|
1379
|
-
prodex tasks block <task-id> [--cwd /absolute/path/to/repo] --summary "Summary" [--code code] [--next-step "Next step"] [--retryable]`);
|
|
1380
|
-
}
|
|
1381
|
-
function printResultsHelp(stdout) {
|
|
1382
|
-
stdout(`prodex results
|
|
1383
|
-
|
|
1384
|
-
Commands:
|
|
1385
|
-
prodex results show <task-id|latest> [--cwd /absolute/path/to/repo]
|
|
1386
|
-
prodex results artifact <task-id|latest> [artifact-path] [--cwd /absolute/path/to/repo]
|
|
1387
|
-
prodex results reseal <task-id|latest> --confirm-current-result [--cwd /absolute/path/to/repo]`);
|
|
1388
|
-
}
|
|
1389
|
-
function printReceiptsHelp(stdout) {
|
|
1390
|
-
stdout(`prodex receipts
|
|
1391
|
-
|
|
1392
|
-
Commands:
|
|
1393
|
-
prodex receipts list [--kind kind] [--task-id task-id] [--cwd /absolute/path/to/repo]
|
|
1394
|
-
prodex receipts show <receipt-id|latest> [--cwd /absolute/path/to/repo]
|
|
1395
|
-
prodex receipts rotate-key [--cwd /absolute/path/to/repo]
|
|
1396
|
-
|
|
1397
|
-
rotate-key generates a new signing key for receipt integrity seals and keeps the
|
|
1398
|
-
previous keys in .bridge/receipt-key.local so receipts signed before the
|
|
1399
|
-
rotation still verify.`);
|
|
1400
|
-
}
|
|
1401
|
-
function printSessionsHelp(stdout) {
|
|
1402
|
-
stdout(`prodex sessions
|
|
1403
|
-
|
|
1404
|
-
Commands:
|
|
1405
|
-
prodex sessions list [--status preview|running|done|blocked] [--cwd /absolute/path/to/repo]
|
|
1406
|
-
prodex sessions show <session-id|latest> [--cwd /absolute/path/to/repo]`);
|
|
1407
|
-
}
|
|
1408
|
-
function isHelpSubcommand(value) {
|
|
1409
|
-
return value === "help" || value === "--help" || value === "-h";
|
|
1410
|
-
}
|
|
1411
1172
|
function isHelpArgs(args) {
|
|
1412
1173
|
return args.length > 0 && isHelpSubcommand(args[0]);
|
|
1413
1174
|
}
|
|
@@ -1427,84 +1188,6 @@ function printProBrowserHelpIfRequested(args, command, io, options) {
|
|
|
1427
1188
|
printProBrowserHelp(io.stdout, resolveOptionalFileFlag(io.cwd, args, "--source-cli"));
|
|
1428
1189
|
return true;
|
|
1429
1190
|
}
|
|
1430
|
-
function findHelpFlagIndexBeforePromptDelimiter(args) {
|
|
1431
|
-
const delimiterIndex = args.indexOf("--");
|
|
1432
|
-
const limit = delimiterIndex === -1 ? args.length : delimiterIndex;
|
|
1433
|
-
return args.findIndex((arg, index) => index < limit && isHelpSubcommand(arg));
|
|
1434
|
-
}
|
|
1435
|
-
function assertHelpRequestArgs(args, command, options) {
|
|
1436
|
-
const delimiterIndex = args.indexOf("--");
|
|
1437
|
-
const commandArgs = delimiterIndex === -1 ? args : args.slice(0, delimiterIndex);
|
|
1438
|
-
const valueFlagSet = new Set(options.valueFlags ?? []);
|
|
1439
|
-
const booleanFlagSet = new Set(options.booleanFlags ?? []);
|
|
1440
|
-
const maxPositionals = options.maxPositionals ?? 0;
|
|
1441
|
-
let positionals = 0;
|
|
1442
|
-
for (let index = 0; index < commandArgs.length; index += 1) {
|
|
1443
|
-
const arg = commandArgs[index];
|
|
1444
|
-
if (isHelpSubcommand(arg))
|
|
1445
|
-
continue;
|
|
1446
|
-
if (valueFlagSet.has(arg)) {
|
|
1447
|
-
const next = commandArgs[index + 1];
|
|
1448
|
-
if (next && !isHelpSubcommand(next)) {
|
|
1449
|
-
readFlagValue(commandArgs, index, arg);
|
|
1450
|
-
index += 1;
|
|
1451
|
-
}
|
|
1452
|
-
continue;
|
|
1453
|
-
}
|
|
1454
|
-
if (booleanFlagSet.has(arg))
|
|
1455
|
-
continue;
|
|
1456
|
-
if (arg.startsWith("-")) {
|
|
1457
|
-
throw unknownOptionError(arg, command, [...valueFlagSet, ...booleanFlagSet]);
|
|
1458
|
-
}
|
|
1459
|
-
if (positionals >= maxPositionals) {
|
|
1460
|
-
throw new Error(`Unexpected argument for ${command}: ${arg}`);
|
|
1461
|
-
}
|
|
1462
|
-
positionals += 1;
|
|
1463
|
-
}
|
|
1464
|
-
}
|
|
1465
|
-
function unknownSubcommandError(command, subcommand, expected) {
|
|
1466
|
-
const suggestion = closestSuggestion(subcommand, expected);
|
|
1467
|
-
const suggestionText = suggestion ? ` Did you mean \`prodex ${command} ${suggestion}\`?` : "";
|
|
1468
|
-
return new Error(`Unknown ${command} subcommand: ${subcommand}.${suggestionText} Expected one of: ${expected.join(", ")}. Run \`prodex ${command} --help\`.`);
|
|
1469
|
-
}
|
|
1470
|
-
function unknownTopLevelCommandError(command) {
|
|
1471
|
-
const suggestion = closestSuggestion(command, TOP_LEVEL_COMMANDS);
|
|
1472
|
-
const suggestionText = suggestion ? ` Did you mean \`prodex ${suggestion}\`?` : "";
|
|
1473
|
-
return new Error(`Unknown command: ${command}.${suggestionText} Run \`prodex help\`.`);
|
|
1474
|
-
}
|
|
1475
|
-
function unknownOptionError(option, command, candidates) {
|
|
1476
|
-
const suggestion = closestSuggestion(option, candidates);
|
|
1477
|
-
const suggestionText = suggestion ? `. Did you mean \`${suggestion}\`?` : "";
|
|
1478
|
-
const context = command ? ` for ${command}` : "";
|
|
1479
|
-
return new Error(`Unknown option${context}: ${option}${suggestionText}`);
|
|
1480
|
-
}
|
|
1481
|
-
function closestSuggestion(value, candidates) {
|
|
1482
|
-
let best;
|
|
1483
|
-
for (const candidate of candidates) {
|
|
1484
|
-
const distance = editDistance(value, candidate);
|
|
1485
|
-
const prefixMatch = isUsefulPrefixSuggestion(value, candidate);
|
|
1486
|
-
if (!best || (prefixMatch && !best.prefixMatch) || (prefixMatch === best.prefixMatch && distance < best.distance)) {
|
|
1487
|
-
best = { command: candidate, distance, prefixMatch };
|
|
1488
|
-
}
|
|
1489
|
-
}
|
|
1490
|
-
return best && (best.prefixMatch || best.distance <= 2) ? best.command : undefined;
|
|
1491
|
-
}
|
|
1492
|
-
function isUsefulPrefixSuggestion(value, candidate) {
|
|
1493
|
-
return value.length >= 5 && candidate.startsWith(value);
|
|
1494
|
-
}
|
|
1495
|
-
function editDistance(left, right) {
|
|
1496
|
-
const previous = Array.from({ length: right.length + 1 }, (_, index) => index);
|
|
1497
|
-
const current = Array.from({ length: right.length + 1 }, () => 0);
|
|
1498
|
-
for (let leftIndex = 1; leftIndex <= left.length; leftIndex += 1) {
|
|
1499
|
-
current[0] = leftIndex;
|
|
1500
|
-
for (let rightIndex = 1; rightIndex <= right.length; rightIndex += 1) {
|
|
1501
|
-
const substitutionCost = left[leftIndex - 1] === right[rightIndex - 1] ? 0 : 1;
|
|
1502
|
-
current[rightIndex] = Math.min(previous[rightIndex] + 1, current[rightIndex - 1] + 1, previous[rightIndex - 1] + substitutionCost);
|
|
1503
|
-
}
|
|
1504
|
-
previous.splice(0, previous.length, ...current);
|
|
1505
|
-
}
|
|
1506
|
-
return previous[right.length];
|
|
1507
|
-
}
|
|
1508
1191
|
function legacyChatGptNamespaceError(subcommand) {
|
|
1509
1192
|
const prefix = subcommand ? `Unknown legacy chatgpt subcommand: ${subcommand}.` : "The legacy `chatgpt` namespace is hidden.";
|
|
1510
1193
|
return new Error(`${prefix} Use \`prodex pro browser help\` for visible-browser commands.`);
|
|
@@ -1682,21 +1365,12 @@ function formatClaudeConfig(cwd, sourceCli) {
|
|
|
1682
1365
|
}
|
|
1683
1366
|
}, null, 2);
|
|
1684
1367
|
}
|
|
1685
|
-
function shellQuote(value) {
|
|
1686
|
-
return /^[A-Za-z0-9_./:@=-]+$/.test(value) ? value : `'${value.replaceAll("'", "'\\''")}'`;
|
|
1687
|
-
}
|
|
1688
|
-
function formatCliCommand(sourceCli) {
|
|
1689
|
-
return sourceCli ? `node ${shellQuote(sourceCli)}` : "prodex";
|
|
1690
|
-
}
|
|
1691
1368
|
function formatInitCommand(sourceCli, options = {}) {
|
|
1692
1369
|
return [`${formatCliCommand(sourceCli)} init`, options.cwd ? `--cwd ${shellQuote(options.cwd)}` : undefined].filter(Boolean).join(" ");
|
|
1693
1370
|
}
|
|
1694
1371
|
function formatSetupCommand(sourceCli, options = {}) {
|
|
1695
1372
|
return [`${formatCliCommand(sourceCli)} setup`, options.cwd ? `--cwd ${shellQuote(options.cwd)}` : undefined].filter(Boolean).join(" ");
|
|
1696
1373
|
}
|
|
1697
|
-
function formatSourceCliOption(sourceCli) {
|
|
1698
|
-
return sourceCli ? ` --source-cli ${shellQuote(sourceCli)}` : "";
|
|
1699
|
-
}
|
|
1700
1374
|
function formatBrowserLoginCommand(sourceCli, options = {}) {
|
|
1701
1375
|
return formatCommandInCwd(formatBrowserLoginCommandBody(sourceCli, options), options.cwd);
|
|
1702
1376
|
}
|
|
@@ -2765,46 +2439,6 @@ function printBrowserLoginGuide(stdout, input) {
|
|
|
2765
2439
|
stdout("The dedicated profile path above will be reused by the real login command.");
|
|
2766
2440
|
}
|
|
2767
2441
|
}
|
|
2768
|
-
function printProBrowserHelp(stdout, sourceCli) {
|
|
2769
|
-
const cli = formatCliCommand(sourceCli);
|
|
2770
|
-
const sourceCliOption = formatSourceCliOption(sourceCli);
|
|
2771
|
-
const loginUsage = sourceCli
|
|
2772
|
-
? `${cli} pro browser login${sourceCliOption} [--cwd /absolute/path/to/repo] [--dry-run] [--profile-dir path] [--port 9333] [--url https://chatgpt.com/...] [--launch-timeout-ms 5000]`
|
|
2773
|
-
: "prodex pro browser login [--cwd /absolute/path/to/repo] [--dry-run] [--source-cli /absolute/path/to/dist/cli.js] [--profile-dir path] [--port 9333] [--url https://chatgpt.com/...] [--launch-timeout-ms 5000]";
|
|
2774
|
-
const checkUsage = sourceCli
|
|
2775
|
-
? `${cli} pro browser check${sourceCliOption} [--cwd /absolute/path/to/repo] [--port 9333] [--timeout-ms 1500]`
|
|
2776
|
-
: "prodex pro browser check [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo] [--port 9333] [--timeout-ms 1500]";
|
|
2777
|
-
const smokeUsage = sourceCli
|
|
2778
|
-
? `${cli} pro browser smoke${sourceCliOption} [--cwd /absolute/path/to/repo] [--port 9333] [--timeout-ms 90000]`
|
|
2779
|
-
: "prodex pro browser smoke [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo] [--port 9333] [--timeout-ms 90000]";
|
|
2780
|
-
const selectionUsage = '[--model Pro] [--pro-mode 기본|확장] [--effort 즉시|중간|높음|"매우 높음"] [--project "name" | --project-new "name"]';
|
|
2781
|
-
const askUsage = sourceCli
|
|
2782
|
-
? `${cli} pro browser ask${sourceCliOption} [--cwd /absolute/path/to/repo] [--port 9333] [--timeout-ms 90000] [--target-url url --confirm-target] [--file path] ${selectionUsage} "prompt"`
|
|
2783
|
-
: `prodex pro browser ask [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo] [--port 9333] [--timeout-ms 90000] [--target-url url --confirm-target] [--file path] ${selectionUsage} "prompt"`;
|
|
2784
|
-
const modelsUsage = sourceCli
|
|
2785
|
-
? `${cli} pro browser models${sourceCliOption} [--port 9333] [--timeout-ms 15000]`
|
|
2786
|
-
: "prodex pro browser models [--source-cli /absolute/path/to/dist/cli.js] [--port 9333] [--timeout-ms 15000]";
|
|
2787
|
-
stdout(`${cli} pro browser
|
|
2788
|
-
|
|
2789
|
-
Commands:
|
|
2790
|
-
${loginUsage}
|
|
2791
|
-
${checkUsage}
|
|
2792
|
-
${smokeUsage}
|
|
2793
|
-
${modelsUsage}
|
|
2794
|
-
${askUsage}
|
|
2795
|
-
|
|
2796
|
-
Visible-browser sends require a manual browser session and stop on login, captcha, Cloudflare, permission, rate-limit, or usage-limit blockers.
|
|
2797
|
-
Model/project selection (ask):
|
|
2798
|
-
--model Composer model to pick by its exact menu label (verified: Pro). Models whose menu entry opens a submenu of variants are rejected with a clear error for now.
|
|
2799
|
-
--pro-mode Pro sub-mode: 기본 (standard) or 확장 (extended), used when the model is Pro. 확장 raises the default --timeout-ms to 300000.
|
|
2800
|
-
--effort Reasoning effort: 즉시 / 중간 / 높음 / 매우 높음 (aliases: instant/medium/high/max). Picking an effort switches the composer to the standard reasoning model, deselecting Pro.
|
|
2801
|
-
--project Enter an existing sidebar project before sending. Cannot be combined with --target-url.
|
|
2802
|
-
--pro-mode and --effort cannot be combined. These labels match the Korean ChatGPT UI; set your ChatGPT display language to Korean for selection flags.
|
|
2803
|
-
Run \`${cli} pro browser models${sourceCliOption}\` to list the labels your account currently shows.
|
|
2804
|
-
Persist defaults with \`${cli} setup${sourceCliOption}\`; per-ask flags override them.
|
|
2805
|
-
Use \`${cli} pro ask\` for dry-run/manual previews.
|
|
2806
|
-
\`${cli} pro browser ask${sourceCliOption}\` always attempts an explicit visible-browser send.`);
|
|
2807
|
-
}
|
|
2808
2442
|
async function assertBrowserLaunchStayedAlive(opened, timeoutMs) {
|
|
2809
2443
|
const outcome = await waitForBrowserLaunchReady(opened, timeoutMs);
|
|
2810
2444
|
if (outcome.reachable)
|
|
@@ -3342,167 +2976,19 @@ function parseTunnelPublicUrl(publicUrl) {
|
|
|
3342
2976
|
function isLoopbackHost(hostname) {
|
|
3343
2977
|
return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1" || hostname === "[::1]";
|
|
3344
2978
|
}
|
|
3345
|
-
function readFlag(args, flag) {
|
|
3346
|
-
const index = args.indexOf(flag);
|
|
3347
|
-
if (index === -1)
|
|
3348
|
-
return undefined;
|
|
3349
|
-
return readFlagValue(args, index, flag);
|
|
3350
|
-
}
|
|
3351
|
-
function readNumberFlag(args, flag) {
|
|
3352
|
-
const raw = readFlag(args, flag);
|
|
3353
|
-
if (raw === undefined)
|
|
3354
|
-
return undefined;
|
|
3355
|
-
const value = Number(raw);
|
|
3356
|
-
if (!Number.isFinite(value))
|
|
3357
|
-
throw new Error(`${flag} requires a finite number`);
|
|
3358
|
-
return value;
|
|
3359
|
-
}
|
|
3360
|
-
function readPositiveNumberFlag(args, flag) {
|
|
3361
|
-
const value = readNumberFlag(args, flag);
|
|
3362
|
-
if (value === undefined)
|
|
3363
|
-
return undefined;
|
|
3364
|
-
if (value <= 0)
|
|
3365
|
-
throw new Error(`${flag} must be greater than 0`);
|
|
3366
|
-
return value;
|
|
3367
|
-
}
|
|
3368
|
-
function readPortFlag(args, flag) {
|
|
3369
|
-
const value = readNumberFlag(args, flag);
|
|
3370
|
-
if (value === undefined)
|
|
3371
|
-
return undefined;
|
|
3372
|
-
if (!Number.isInteger(value) || value < 1 || value > 65535) {
|
|
3373
|
-
throw new Error(`${flag} must be an integer from 1 to 65535`);
|
|
3374
|
-
}
|
|
3375
|
-
return value;
|
|
3376
|
-
}
|
|
3377
2979
|
function readChatGptBrowserUrlFlag(args) {
|
|
3378
2980
|
return normalizeChatGptTargetUrl(readFlag(args, "--url") ?? "https://chatgpt.com/");
|
|
3379
2981
|
}
|
|
3380
|
-
function readRepeatedFlag(args, flag) {
|
|
3381
|
-
const values = [];
|
|
3382
|
-
for (let index = 0; index < args.length; index += 1) {
|
|
3383
|
-
if (args[index] === flag) {
|
|
3384
|
-
values.push(readFlagValue(args, index, flag));
|
|
3385
|
-
index += 1;
|
|
3386
|
-
}
|
|
3387
|
-
}
|
|
3388
|
-
return values;
|
|
3389
|
-
}
|
|
3390
|
-
function resolveCwdFlag(defaultCwd, args) {
|
|
3391
|
-
const cwd = readFlag(args, "--cwd");
|
|
3392
|
-
if (!cwd)
|
|
3393
|
-
return defaultCwd;
|
|
3394
|
-
return resolveExistingDirectoryFlag(defaultCwd, cwd, "--cwd");
|
|
3395
|
-
}
|
|
3396
2982
|
function resolveOptionalPathFlag(defaultCwd, args, flag) {
|
|
3397
2983
|
const value = readFlag(args, flag);
|
|
3398
2984
|
return value ? resolveExistingPathFlag(defaultCwd, value, flag) : undefined;
|
|
3399
2985
|
}
|
|
3400
|
-
function resolveOptionalFileFlag(defaultCwd, args, flag) {
|
|
3401
|
-
const value = readFlag(args, flag);
|
|
3402
|
-
return value ? resolveExistingFileFlag(defaultCwd, value, flag) : undefined;
|
|
3403
|
-
}
|
|
3404
|
-
function resolveExistingPathFlag(defaultCwd, value, flag) {
|
|
3405
|
-
const resolved = path.resolve(defaultCwd, value);
|
|
3406
|
-
try {
|
|
3407
|
-
return realpathSync(resolved);
|
|
3408
|
-
}
|
|
3409
|
-
catch {
|
|
3410
|
-
throw new Error(`${flag} does not exist or is not accessible: ${resolved}`);
|
|
3411
|
-
}
|
|
3412
|
-
}
|
|
3413
|
-
function resolveExistingFileFlag(defaultCwd, value, flag) {
|
|
3414
|
-
const resolved = resolveExistingPathFlag(defaultCwd, value, flag);
|
|
3415
|
-
if (!statSync(resolved).isFile()) {
|
|
3416
|
-
throw new Error(`${flag} must be a file: ${resolved}`);
|
|
3417
|
-
}
|
|
3418
|
-
return resolved;
|
|
3419
|
-
}
|
|
3420
|
-
function resolveExistingDirectoryFlag(defaultCwd, value, flag) {
|
|
3421
|
-
const resolved = resolveExistingPathFlag(defaultCwd, value, flag);
|
|
3422
|
-
if (!statSync(resolved).isDirectory()) {
|
|
3423
|
-
throw new Error(`${flag} must be a directory: ${resolved}`);
|
|
3424
|
-
}
|
|
3425
|
-
return resolved;
|
|
3426
|
-
}
|
|
3427
|
-
function assertOnlyOptions(args, command, valueFlags, booleanFlags = []) {
|
|
3428
|
-
const valueFlagSet = new Set(valueFlags);
|
|
3429
|
-
const booleanFlagSet = new Set(booleanFlags);
|
|
3430
|
-
for (let index = 0; index < args.length; index += 1) {
|
|
3431
|
-
const arg = args[index];
|
|
3432
|
-
if (valueFlagSet.has(arg)) {
|
|
3433
|
-
readFlagValue(args, index, arg);
|
|
3434
|
-
index += 1;
|
|
3435
|
-
continue;
|
|
3436
|
-
}
|
|
3437
|
-
if (booleanFlagSet.has(arg))
|
|
3438
|
-
continue;
|
|
3439
|
-
if (arg.startsWith("-")) {
|
|
3440
|
-
throw unknownOptionError(arg, command, [...valueFlagSet, ...booleanFlagSet]);
|
|
3441
|
-
}
|
|
3442
|
-
throw new Error(`Unexpected argument for ${command}: ${arg}`);
|
|
3443
|
-
}
|
|
3444
|
-
}
|
|
3445
|
-
function readPositionalsWithOptions(args, command, maxPositionals, valueFlags, booleanFlags = []) {
|
|
3446
|
-
const valueFlagSet = new Set(valueFlags);
|
|
3447
|
-
const booleanFlagSet = new Set(booleanFlags);
|
|
3448
|
-
const positionals = [];
|
|
3449
|
-
for (let index = 0; index < args.length; index += 1) {
|
|
3450
|
-
const arg = args[index];
|
|
3451
|
-
if (valueFlagSet.has(arg)) {
|
|
3452
|
-
readFlagValue(args, index, arg);
|
|
3453
|
-
index += 1;
|
|
3454
|
-
continue;
|
|
3455
|
-
}
|
|
3456
|
-
if (booleanFlagSet.has(arg))
|
|
3457
|
-
continue;
|
|
3458
|
-
if (arg.startsWith("-")) {
|
|
3459
|
-
throw unknownOptionError(arg, command, [...valueFlagSet, ...booleanFlagSet]);
|
|
3460
|
-
}
|
|
3461
|
-
if (positionals.length >= maxPositionals) {
|
|
3462
|
-
throw new Error(`Unexpected argument for ${command}: ${arg}`);
|
|
3463
|
-
}
|
|
3464
|
-
positionals.push(arg);
|
|
3465
|
-
}
|
|
3466
|
-
return positionals;
|
|
3467
|
-
}
|
|
3468
|
-
function assertNoExtraArgs(args, command, maxPositionals) {
|
|
3469
|
-
for (const arg of args.slice(maxPositionals)) {
|
|
3470
|
-
if (arg.startsWith("-")) {
|
|
3471
|
-
throw new Error(`Unknown option for ${command}: ${arg}`);
|
|
3472
|
-
}
|
|
3473
|
-
throw new Error(`Unexpected argument for ${command}: ${arg}`);
|
|
3474
|
-
}
|
|
3475
|
-
}
|
|
3476
2986
|
function readRequiredLeadingArgument(args, command, placeholder) {
|
|
3477
2987
|
const value = args[0];
|
|
3478
2988
|
if (!value || value.startsWith("-"))
|
|
3479
2989
|
throw new Error(`${command} requires ${placeholder}`);
|
|
3480
2990
|
return value;
|
|
3481
2991
|
}
|
|
3482
|
-
const ASK_PRO_BOOLEAN_FLAGS = new Set(["--dry-run", "--send", "--confirm-target"]);
|
|
3483
|
-
const ASK_PRO_SELECTION_VALUE_FLAGS = ["--project", "--project-new", "--model", "--pro-mode", "--effort"];
|
|
3484
|
-
const ASK_PRO_VALUE_FLAGS = new Set([
|
|
3485
|
-
"--cwd",
|
|
3486
|
-
"--file",
|
|
3487
|
-
"--port",
|
|
3488
|
-
"--timeout-ms",
|
|
3489
|
-
"--target-url",
|
|
3490
|
-
"--source-cli",
|
|
3491
|
-
...ASK_PRO_SELECTION_VALUE_FLAGS
|
|
3492
|
-
]);
|
|
3493
|
-
const ASK_PRO_PREVIEW_VALUE_FLAGS = new Set([
|
|
3494
|
-
"--cwd",
|
|
3495
|
-
"--file",
|
|
3496
|
-
"--port",
|
|
3497
|
-
"--timeout-ms",
|
|
3498
|
-
"--target-url",
|
|
3499
|
-
...ASK_PRO_SELECTION_VALUE_FLAGS
|
|
3500
|
-
]);
|
|
3501
|
-
// Setup persists defaults for a subset of the per-ask selection flags. A new
|
|
3502
|
-
// project is created per-ask, never as a standing default, so --project-new is
|
|
3503
|
-
// intentionally excluded here.
|
|
3504
|
-
const ASK_PRO_SELECTION_DEFAULT_FLAGS = ["--model", "--pro-mode", "--effort", "--project"];
|
|
3505
|
-
const ASK_PRO_SELECTION_CLEAR_FLAGS = ["--clear-model", "--clear-pro-mode", "--clear-effort", "--clear-project"];
|
|
3506
2992
|
function parseBrowserDefaultFlags(args) {
|
|
3507
2993
|
const model = readFlag(args, "--model");
|
|
3508
2994
|
const proModeRaw = readFlag(args, "--pro-mode");
|
|
@@ -3608,76 +3094,6 @@ function formatBrowserDefaults(defaults) {
|
|
|
3608
3094
|
parts.push(`project=${defaults.project}`);
|
|
3609
3095
|
return parts.length > 0 ? parts.join(", ") : "(none)";
|
|
3610
3096
|
}
|
|
3611
|
-
function parseAskProArgs(args, valueFlags = ASK_PRO_VALUE_FLAGS) {
|
|
3612
|
-
const delimiterIndex = args.indexOf("--");
|
|
3613
|
-
const optionArgs = delimiterIndex === -1 ? args : args.slice(0, delimiterIndex);
|
|
3614
|
-
const promptTail = delimiterIndex === -1 ? [] : args.slice(delimiterIndex + 1);
|
|
3615
|
-
const positionalPromptParts = [];
|
|
3616
|
-
for (let index = 0; index < optionArgs.length; index += 1) {
|
|
3617
|
-
const arg = optionArgs[index];
|
|
3618
|
-
if (!arg.startsWith("--")) {
|
|
3619
|
-
if (arg.startsWith("-"))
|
|
3620
|
-
throw unknownOptionError(arg, undefined, [...valueFlags, ...ASK_PRO_BOOLEAN_FLAGS]);
|
|
3621
|
-
positionalPromptParts.push(arg);
|
|
3622
|
-
continue;
|
|
3623
|
-
}
|
|
3624
|
-
if (ASK_PRO_BOOLEAN_FLAGS.has(arg))
|
|
3625
|
-
continue;
|
|
3626
|
-
if (valueFlags.has(arg)) {
|
|
3627
|
-
readFlagValue(optionArgs, index, arg);
|
|
3628
|
-
index += 1;
|
|
3629
|
-
continue;
|
|
3630
|
-
}
|
|
3631
|
-
throw unknownOptionError(arg, undefined, [...valueFlags, ...ASK_PRO_BOOLEAN_FLAGS]);
|
|
3632
|
-
}
|
|
3633
|
-
return { optionArgs, promptParts: [...positionalPromptParts, ...promptTail] };
|
|
3634
|
-
}
|
|
3635
|
-
function askProOptionArgs(args) {
|
|
3636
|
-
const delimiterIndex = args.indexOf("--");
|
|
3637
|
-
return delimiterIndex === -1 ? args : args.slice(0, delimiterIndex);
|
|
3638
|
-
}
|
|
3639
|
-
function hasAskProMode(args) {
|
|
3640
|
-
const optionArgs = askProOptionArgs(args);
|
|
3641
|
-
return optionArgs.includes("--send") || optionArgs.includes("--dry-run");
|
|
3642
|
-
}
|
|
3643
|
-
function hasAskProSendMode(args) {
|
|
3644
|
-
return askProOptionArgs(args).includes("--send");
|
|
3645
|
-
}
|
|
3646
|
-
function hasAskProDryRunMode(args) {
|
|
3647
|
-
return askProOptionArgs(args).includes("--dry-run");
|
|
3648
|
-
}
|
|
3649
|
-
function readFlagValue(args, index, flag) {
|
|
3650
|
-
const value = args[index + 1];
|
|
3651
|
-
if (!value || value.startsWith("--"))
|
|
3652
|
-
throw new Error(`${flag} requires a value`);
|
|
3653
|
-
return value;
|
|
3654
|
-
}
|
|
3655
|
-
function readSessionStatusFlag(args) {
|
|
3656
|
-
const value = readFlag(args, "--status");
|
|
3657
|
-
if (value === undefined)
|
|
3658
|
-
return undefined;
|
|
3659
|
-
if (value === "preview" || value === "running" || value === "done" || value === "blocked")
|
|
3660
|
-
return value;
|
|
3661
|
-
throw new Error("--status must be one of preview, running, done, blocked");
|
|
3662
|
-
}
|
|
3663
|
-
const TASK_STATUSES = TaskStatusSchema.options;
|
|
3664
|
-
function readTaskStatusFlag(args) {
|
|
3665
|
-
const value = readFlag(args, "--status");
|
|
3666
|
-
if (value === undefined)
|
|
3667
|
-
return undefined;
|
|
3668
|
-
if (TaskStatusSchema.safeParse(value).success)
|
|
3669
|
-
return value;
|
|
3670
|
-
throw new Error(`--status must be one of ${TASK_STATUSES.join(", ")}`);
|
|
3671
|
-
}
|
|
3672
|
-
const RECEIPT_KINDS = ReceiptKindSchema.options;
|
|
3673
|
-
function readReceiptKindFlag(args) {
|
|
3674
|
-
const value = readFlag(args, "--kind");
|
|
3675
|
-
if (value === undefined)
|
|
3676
|
-
return undefined;
|
|
3677
|
-
if (ReceiptKindSchema.safeParse(value).success)
|
|
3678
|
-
return value;
|
|
3679
|
-
throw new Error(`--kind must be one of ${RECEIPT_KINDS.join(", ")}`);
|
|
3680
|
-
}
|
|
3681
3097
|
function formatTokenExpiryLine(config) {
|
|
3682
3098
|
const tokenStatus = getTokenExpiryStatus(config);
|
|
3683
3099
|
if (tokenStatus.status === "valid")
|