@youdie006/prodex 0.16.1 → 0.16.3
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/banner.js +0 -1
- package/dist/bundle.js +0 -1
- package/dist/chatgpt-browser.js +0 -1
- package/dist/cli-args.js +0 -1
- package/dist/cli-help.js +5 -5
- package/dist/cli-ledger.js +0 -1
- package/dist/cli-pro.js +24 -13
- package/dist/cli-server.js +0 -1
- package/dist/cli-shared.js +0 -1
- package/dist/cli.js +0 -1
- package/dist/config.js +0 -1
- package/dist/http-mcp.js +6 -2
- package/dist/index.js +0 -1
- package/dist/mcp-tools.js +0 -1
- package/dist/mcp.js +15 -2
- package/dist/registry.js +0 -1
- package/dist/repo-write.js +0 -1
- package/dist/repo.js +0 -1
- package/dist/safe-file.js +0 -1
- package/dist/schema.js +0 -1
- package/dist/store.js +24 -2
- package/package.json +1 -1
- package/dist/banner.d.ts +0 -5
- package/dist/banner.js.map +0 -1
- package/dist/bundle.d.ts +0 -15
- package/dist/bundle.js.map +0 -1
- package/dist/chatgpt-browser.d.ts +0 -252
- package/dist/chatgpt-browser.js.map +0 -1
- package/dist/cli-args.d.ts +0 -54
- package/dist/cli-args.js.map +0 -1
- package/dist/cli-help.d.ts +0 -20
- package/dist/cli-help.js.map +0 -1
- package/dist/cli-ledger.d.ts +0 -22
- package/dist/cli-ledger.js.map +0 -1
- package/dist/cli-pro.d.ts +0 -157
- package/dist/cli-pro.js.map +0 -1
- package/dist/cli-server.d.ts +0 -42
- package/dist/cli-server.js.map +0 -1
- package/dist/cli-shared.d.ts +0 -68
- package/dist/cli-shared.js.map +0 -1
- package/dist/cli.d.ts +0 -14
- package/dist/cli.js.map +0 -1
- package/dist/config.d.ts +0 -110
- package/dist/config.js.map +0 -1
- package/dist/http-mcp.d.ts +0 -20
- package/dist/http-mcp.js.map +0 -1
- package/dist/index.d.ts +0 -8
- package/dist/index.js.map +0 -1
- package/dist/mcp-tools.d.ts +0 -395
- package/dist/mcp-tools.js.map +0 -1
- package/dist/mcp.d.ts +0 -57
- package/dist/mcp.js.map +0 -1
- package/dist/registry.d.ts +0 -8
- package/dist/registry.js.map +0 -1
- package/dist/repo-write.d.ts +0 -47
- package/dist/repo-write.js.map +0 -1
- package/dist/repo.d.ts +0 -28
- package/dist/repo.js.map +0 -1
- package/dist/safe-file.d.ts +0 -25
- package/dist/safe-file.js.map +0 -1
- package/dist/schema.d.ts +0 -402
- package/dist/schema.js.map +0 -1
- package/dist/store.d.ts +0 -164
- package/dist/store.js.map +0 -1
package/dist/banner.js
CHANGED
package/dist/bundle.js
CHANGED
package/dist/chatgpt-browser.js
CHANGED
package/dist/cli-args.js
CHANGED
package/dist/cli-help.js
CHANGED
|
@@ -31,12 +31,12 @@ Ask / consult commands:
|
|
|
31
31
|
|
|
32
32
|
Bridge ledger (durable tasks/results/receipts/sessions under .bridge/):
|
|
33
33
|
prodex init [--cwd /absolute/path/to/repo]
|
|
34
|
-
prodex tasks create [--cwd /absolute/path/to/repo] --title "Title" --prompt "Prompt"
|
|
34
|
+
prodex tasks create [--cwd /absolute/path/to/repo] --title "Title" --prompt "Prompt" [--repo-id id] [--file path]
|
|
35
35
|
prodex tasks list [--status new|claimed|done|blocked] [--cwd /absolute/path/to/repo] [--json]
|
|
36
36
|
prodex tasks show <task-id|latest> [--cwd /absolute/path/to/repo]
|
|
37
37
|
prodex tasks claim <task-id> [--cwd /absolute/path/to/repo] [--by codex]
|
|
38
38
|
prodex tasks complete <task-id> [--cwd /absolute/path/to/repo] --summary "Summary" [--command "npm test"] [--artifact .bridge/artifacts/results/name.md=text]
|
|
39
|
-
prodex tasks block <task-id> [--cwd /absolute/path/to/repo] --summary "Summary" [--code code] [--next-step "Next step"] [--retryable]
|
|
39
|
+
prodex tasks block <task-id> [--cwd /absolute/path/to/repo] --summary "Summary" [--code code] [--next-step "Next step"] [--retryable] [--command "npm test"]
|
|
40
40
|
prodex results show <task-id|latest> [--cwd /absolute/path/to/repo]
|
|
41
41
|
prodex results artifact <task-id|latest> [artifact-path] [--cwd /absolute/path/to/repo]
|
|
42
42
|
prodex results reseal <task-id|latest> --confirm-current-result [--cwd /absolute/path/to/repo]
|
|
@@ -45,6 +45,7 @@ Bridge ledger (durable tasks/results/receipts/sessions under .bridge/):
|
|
|
45
45
|
prodex receipts rotate-key [--cwd /absolute/path/to/repo]
|
|
46
46
|
prodex sessions list [--status preview|running|done|blocked] [--cwd /absolute/path/to/repo] [--json]
|
|
47
47
|
prodex sessions show <session-id|latest> [--cwd /absolute/path/to/repo]
|
|
48
|
+
prodex sessions cancel <session-id|latest> [--cwd /absolute/path/to/repo]
|
|
48
49
|
|
|
49
50
|
Agent / MCP integration:
|
|
50
51
|
prodex mcp [--cwd /absolute/path/to/repo]
|
|
@@ -200,12 +201,12 @@ export function printTasksHelp(stdout) {
|
|
|
200
201
|
stdout(`prodex tasks
|
|
201
202
|
|
|
202
203
|
Commands:
|
|
203
|
-
prodex tasks create [--cwd /absolute/path/to/repo] --title "Title" --prompt "Prompt"
|
|
204
|
+
prodex tasks create [--cwd /absolute/path/to/repo] --title "Title" --prompt "Prompt" [--repo-id id] [--file path]
|
|
204
205
|
prodex tasks list [--status new|claimed|done|blocked] [--cwd /absolute/path/to/repo] [--json]
|
|
205
206
|
prodex tasks show <task-id|latest> [--cwd /absolute/path/to/repo]
|
|
206
207
|
prodex tasks claim <task-id> [--cwd /absolute/path/to/repo] [--by codex]
|
|
207
208
|
prodex tasks complete <task-id> [--cwd /absolute/path/to/repo] --summary "Summary" [--command "npm test"] [--artifact .bridge/artifacts/results/name.md=text]
|
|
208
|
-
prodex tasks block <task-id> [--cwd /absolute/path/to/repo] --summary "Summary" [--code code] [--next-step "Next step"] [--retryable]`);
|
|
209
|
+
prodex tasks block <task-id> [--cwd /absolute/path/to/repo] --summary "Summary" [--code code] [--next-step "Next step"] [--retryable] [--command "npm test"]`);
|
|
209
210
|
}
|
|
210
211
|
export function printResultsHelp(stdout) {
|
|
211
212
|
stdout(`prodex results
|
|
@@ -275,4 +276,3 @@ Persist defaults with \`${cli} setup${sourceCliOption}\`; per-ask flags override
|
|
|
275
276
|
Use \`${cli} pro ask\` for dry-run/manual previews.
|
|
276
277
|
\`${cli} pro browser ask${sourceCliOption}\` always attempts an explicit visible-browser send.`);
|
|
277
278
|
}
|
|
278
|
-
//# sourceMappingURL=cli-help.js.map
|
package/dist/cli-ledger.js
CHANGED
package/dist/cli-pro.js
CHANGED
|
@@ -215,16 +215,22 @@ export async function runProCommand(rest, io, runCliFn) {
|
|
|
215
215
|
});
|
|
216
216
|
return 0;
|
|
217
217
|
}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
});
|
|
223
|
-
|
|
218
|
+
// If the dedicated Chrome is already reachable on this port, do NOT spawn
|
|
219
|
+
// again: Chrome's singleton would just open ANOTHER window (the recurring
|
|
220
|
+
// "extra windows" problem, which then blocks sends as
|
|
221
|
+
// ambiguous_chatgpt_tabs). Reuse the running instance instead.
|
|
222
|
+
const alreadyRunning = (await getChatGptBrowserStatus({ port })).reachable;
|
|
223
|
+
const opened = alreadyRunning
|
|
224
|
+
? { profileDir: profileDir ?? defaultChatGptProfileDir(), port }
|
|
225
|
+
: openChatGptBrowser({ port, profileDir, url: loginUrl });
|
|
226
|
+
if (!alreadyRunning) {
|
|
227
|
+
await assertBrowserLaunchStayedAlive(opened, launchTimeoutMs);
|
|
228
|
+
}
|
|
224
229
|
// Remember this launch so ask auto-recovery reuses the same profile.
|
|
225
230
|
await recordBrowserLoginLaunch({ profile_dir: opened.profileDir, port: opened.port });
|
|
226
231
|
printBrowserLoginGuide(io.stdout, {
|
|
227
|
-
opened:
|
|
232
|
+
opened: !alreadyRunning,
|
|
233
|
+
reused: alreadyRunning,
|
|
228
234
|
loginUrl,
|
|
229
235
|
profileDir: opened.profileDir,
|
|
230
236
|
port: opened.port,
|
|
@@ -481,8 +487,9 @@ export async function runAskProCommand(rest, io) {
|
|
|
481
487
|
throw new Error("--json applies to the visible-browser send output; the dry-run preview does not support it.");
|
|
482
488
|
}
|
|
483
489
|
const prompt = parsedAskPro.promptParts.join(" ").trim();
|
|
484
|
-
if (!prompt)
|
|
485
|
-
throw new Error(
|
|
490
|
+
if (!prompt) {
|
|
491
|
+
throw new Error('ask-pro requires a prompt. Example: prodex ask "Explain this stack trace" (or pipe input: git diff | prodex ask --stdin "review this diff").');
|
|
492
|
+
}
|
|
486
493
|
let promptText = prompt;
|
|
487
494
|
if (parsedAskPro.optionArgs.includes("--stdin")) {
|
|
488
495
|
// Unix ergonomics: `git diff | prodex ask --stdin "review this"`.
|
|
@@ -1090,6 +1097,7 @@ export async function listConsultListEntries(store, options = { readOnly: true }
|
|
|
1090
1097
|
return entries;
|
|
1091
1098
|
}
|
|
1092
1099
|
export function printBrowserLoginGuide(stdout, input) {
|
|
1100
|
+
const windowAvailable = input.opened || input.reused === true;
|
|
1093
1101
|
const loginCommand = formatBrowserLoginCommand(input.sourceCli, input.commandOptions);
|
|
1094
1102
|
const runtimeCommandOptions = {
|
|
1095
1103
|
...(input.commandOptions?.cwd ? { cwd: input.commandOptions.cwd } : {}),
|
|
@@ -1098,10 +1106,14 @@ export function printBrowserLoginGuide(stdout, input) {
|
|
|
1098
1106
|
const checkCommand = formatBrowserCheckCommand(input.sourceCli, runtimeCommandOptions);
|
|
1099
1107
|
const smokeCommand = formatBrowserSmokeCommand(input.sourceCli, runtimeCommandOptions);
|
|
1100
1108
|
stdout("ChatGPT Pro browser login");
|
|
1101
|
-
stdout(input.
|
|
1109
|
+
stdout(input.reused
|
|
1110
|
+
? "Chrome is already running for ChatGPT - reusing it (no new window opened)."
|
|
1111
|
+
: input.opened
|
|
1112
|
+
? "Opened the dedicated Chrome window for ChatGPT."
|
|
1113
|
+
: "Dry run: no browser was opened.");
|
|
1102
1114
|
stdout("");
|
|
1103
1115
|
stdout("Steps:");
|
|
1104
|
-
if (
|
|
1116
|
+
if (windowAvailable) {
|
|
1105
1117
|
stdout(`1. Log in manually at ${input.loginUrl} in the dedicated Chrome window.`);
|
|
1106
1118
|
stdout("2. If ChatGPT asks for captcha, Cloudflare/human verification, permission, or account verification, complete it in the browser.");
|
|
1107
1119
|
stdout("3. For usage limit, message limit, model limit, or rate limit, wait for the reset or choose an available model in the browser.");
|
|
@@ -1123,7 +1135,7 @@ export function printBrowserLoginGuide(stdout, input) {
|
|
|
1123
1135
|
stdout("");
|
|
1124
1136
|
stdout(`Profile: ${input.profileDir}`);
|
|
1125
1137
|
stdout(`Debug: http://127.0.0.1:${input.port}`);
|
|
1126
|
-
if (
|
|
1138
|
+
if (windowAvailable) {
|
|
1127
1139
|
stdout("You can close this Chrome window after check/smoke or when you are done. The dedicated profile is reused next time.");
|
|
1128
1140
|
}
|
|
1129
1141
|
else {
|
|
@@ -1390,4 +1402,3 @@ export function orphanConsultResultError(taskId) {
|
|
|
1390
1402
|
export function sleep(ms) {
|
|
1391
1403
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1392
1404
|
}
|
|
1393
|
-
//# sourceMappingURL=cli-pro.js.map
|
package/dist/cli-server.js
CHANGED
package/dist/cli-shared.js
CHANGED
package/dist/cli.js
CHANGED
package/dist/config.js
CHANGED
package/dist/http-mcp.js
CHANGED
|
@@ -23,7 +23,12 @@ export async function startHttpMcpServer(options) {
|
|
|
23
23
|
return;
|
|
24
24
|
}
|
|
25
25
|
if (!isAuthorized(req, requestUrl, token, options.tokenExpiresAt)) {
|
|
26
|
-
|
|
26
|
+
// Same 401 for missing/wrong/expired (no oracle), but tell the caller
|
|
27
|
+
// HOW to authorize without leaking anything token-specific.
|
|
28
|
+
writeJson(res, 401, {
|
|
29
|
+
error: "unauthorized",
|
|
30
|
+
hint: "Provide a valid token via `?prodex_token=<token>` or `Authorization: Bearer <token>`. If your token expired, regenerate the profile with `prodex setup` and re-read the URL from `prodex status`."
|
|
31
|
+
});
|
|
27
32
|
return;
|
|
28
33
|
}
|
|
29
34
|
if (req.method === "POST") {
|
|
@@ -233,4 +238,3 @@ function writeJson(res, status, value) {
|
|
|
233
238
|
res.writeHead(status, { "content-type": "application/json" });
|
|
234
239
|
res.end(`${JSON.stringify(value)}\n`);
|
|
235
240
|
}
|
|
236
|
-
//# sourceMappingURL=http-mcp.js.map
|
package/dist/index.js
CHANGED
package/dist/mcp-tools.js
CHANGED
package/dist/mcp.js
CHANGED
|
@@ -279,9 +279,22 @@ export class LimitedStdioServerTransport {
|
|
|
279
279
|
}
|
|
280
280
|
const line = this.buffer.toString("utf8", 0, newlineIndex).replace(/\r$/, "");
|
|
281
281
|
this.buffer = this.buffer.subarray(newlineIndex + 1);
|
|
282
|
-
|
|
282
|
+
if (line.trim().length === 0)
|
|
283
|
+
continue;
|
|
284
|
+
let message;
|
|
285
|
+
try {
|
|
286
|
+
message = JSONRPCMessageSchema.parse(JSON.parse(line));
|
|
287
|
+
}
|
|
288
|
+
catch (error) {
|
|
289
|
+
// A single malformed frame is recoverable: report it and keep
|
|
290
|
+
// processing the rest of the buffer instead of tearing down the whole
|
|
291
|
+
// session (which would also drop any valid pipelined messages after
|
|
292
|
+
// it). This matches the SDK's StdioServerTransport. Only the oversize
|
|
293
|
+
// guards above stay fatal.
|
|
294
|
+
this.onerror?.(error instanceof Error ? error : new Error(String(error)));
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
283
297
|
this.onmessage?.(message);
|
|
284
298
|
}
|
|
285
299
|
}
|
|
286
300
|
}
|
|
287
|
-
//# sourceMappingURL=mcp.js.map
|
package/dist/registry.js
CHANGED
package/dist/repo-write.js
CHANGED
package/dist/repo.js
CHANGED
package/dist/safe-file.js
CHANGED
package/dist/schema.js
CHANGED
package/dist/store.js
CHANGED
|
@@ -273,8 +273,26 @@ export class BridgeStore {
|
|
|
273
273
|
}
|
|
274
274
|
async listFinalizedResultsReadOnly() {
|
|
275
275
|
const results = await this.listResultsReadOnly();
|
|
276
|
+
if (results.length === 0)
|
|
277
|
+
return results;
|
|
278
|
+
if (!(await this.hasReadyStorageDirReadOnly("receipts"))) {
|
|
279
|
+
throw untrustedResultError(this.root, results[0].task_id, "has no trusted task_completed receipt");
|
|
280
|
+
}
|
|
281
|
+
// Read receipts ONCE and index them by task_id instead of re-reading and
|
|
282
|
+
// re-parsing the whole receipts directory for every result, which was
|
|
283
|
+
// O(results x receipts) on the completion/list hot path.
|
|
284
|
+
const completionReceiptsByTask = new Map();
|
|
285
|
+
for (const receipt of await this.readAll("receipts", parseReceiptRecord, { cleanupTempHardLinks: false })) {
|
|
286
|
+
if (receipt.kind !== "task_completed" || !receipt.task_id)
|
|
287
|
+
continue;
|
|
288
|
+
const existing = completionReceiptsByTask.get(receipt.task_id);
|
|
289
|
+
if (existing)
|
|
290
|
+
existing.push(receipt);
|
|
291
|
+
else
|
|
292
|
+
completionReceiptsByTask.set(receipt.task_id, [receipt]);
|
|
293
|
+
}
|
|
276
294
|
for (const result of results) {
|
|
277
|
-
await this.
|
|
295
|
+
await this.assertReceiptsTrustCompletion(result.task_id, result, completionReceiptsByTask.get(result.task_id) ?? []);
|
|
278
296
|
}
|
|
279
297
|
return results;
|
|
280
298
|
}
|
|
@@ -505,6 +523,11 @@ export class BridgeStore {
|
|
|
505
523
|
throw untrustedResultError(this.root, taskId, "has no trusted task_completed receipt");
|
|
506
524
|
}
|
|
507
525
|
const receipts = (await this.readAll("receipts", parseReceiptRecord, { cleanupTempHardLinks: false })).filter((receipt) => receipt.kind === "task_completed" && receipt.task_id === taskId);
|
|
526
|
+
await this.assertReceiptsTrustCompletion(taskId, result, receipts);
|
|
527
|
+
}
|
|
528
|
+
// Given the already-loaded task_completed receipts for one task, accept if any
|
|
529
|
+
// one is locally trusted and its result digest matches; otherwise throw.
|
|
530
|
+
async assertReceiptsTrustCompletion(taskId, result, receipts) {
|
|
508
531
|
if (receipts.length === 0) {
|
|
509
532
|
throw untrustedResultError(this.root, taskId, "has no trusted task_completed receipt");
|
|
510
533
|
}
|
|
@@ -1542,4 +1565,3 @@ function redactReceiptForDisplay(receipt, integrityStatus) {
|
|
|
1542
1565
|
}
|
|
1543
1566
|
return ReceiptSchema.parse({ ...receipt, metadata });
|
|
1544
1567
|
}
|
|
1545
|
-
//# sourceMappingURL=store.js.map
|
package/package.json
CHANGED
package/dist/banner.d.ts
DELETED
package/dist/banner.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"banner.js","sourceRoot":"","sources":["../src/banner.ts"],"names":[],"mappings":"AAKA,kFAAkF;AAClF,8EAA8E;AAC9E,oCAAoC;AACpC,MAAM,QAAQ,GAAG;IACf,2BAA2B;IAC3B,2BAA2B;IAC3B,2BAA2B;IAC3B,2BAA2B;IAC3B,2BAA2B;IAC3B,2BAA2B;CAC5B,CAAC;AAEF,MAAM,QAAQ,GAAG;IACf,0BAA0B;IAC1B,0BAA0B;IAC1B,0BAA0B;IAC1B,0BAA0B;IAC1B,0BAA0B;IAC1B,2BAA2B;CAC5B,CAAC;AAEF,MAAM,GAAG,GAAG,GAAG,CAAC;AAChB,MAAM,GAAG,GAAG,GAAG,GAAG,kBAAkB,CAAC,CAAC,gBAAgB;AACtD,MAAM,GAAG,GAAG,GAAG,GAAG,oBAAoB,CAAC,CAAC,mDAAmD;AAC3F,MAAM,GAAG,GAAG,GAAG,GAAG,oBAAoB,CAAC,CAAC,UAAU;AAClD,MAAM,KAAK,GAAG,GAAG,GAAG,KAAK,CAAC;AAE1B,MAAM,OAAO,GAAG,gEAAgE,CAAC;AAEjF,MAAM,UAAU,YAAY,CAAC,UAAyB,EAAE;IACtD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC;IACpC,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QACxB,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC;IACzE,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACd,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,OAAO,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC;IACjE,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,cAAc,CAAC,MAAyB,OAAO,CAAC,GAAG,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK;IAC/F,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,GAAG,CAAC,QAAQ,KAAK,EAAE;QAAE,OAAO,KAAK,CAAC;IACpE,uHAAuH;IACvH,IAAI,GAAG,CAAC,WAAW,KAAK,SAAS,IAAI,GAAG,CAAC,WAAW,KAAK,EAAE;QAAE,OAAO,GAAG,CAAC,WAAW,KAAK,GAAG,CAAC;IAC5F,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC;AACxB,CAAC"}
|
package/dist/bundle.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { type BridgeFile } from "./schema.js";
|
|
2
|
-
export interface DryRunBundleInput {
|
|
3
|
-
prompt: string;
|
|
4
|
-
files: string[];
|
|
5
|
-
}
|
|
6
|
-
export interface DryRunBundle {
|
|
7
|
-
schema_version: 1;
|
|
8
|
-
id: string;
|
|
9
|
-
mode: "manual_copy";
|
|
10
|
-
prompt: string;
|
|
11
|
-
files: BridgeFile[];
|
|
12
|
-
text: string;
|
|
13
|
-
created_at: string;
|
|
14
|
-
}
|
|
15
|
-
export declare function buildDryRunBundle(root: string, input: DryRunBundleInput): Promise<DryRunBundle>;
|
package/dist/bundle.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bundle.js","sourceRoot":"","sources":["../src/bundle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,cAAc,EAAmB,MAAM,aAAa,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAiBzC,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAY,EAAE,KAAwB;IAC5E,MAAM,QAAQ,GAAa;QACzB,0BAA0B;QAC1B,EAAE;QACF,qCAAqC;QACrC,EAAE;QACF,WAAW;QACX,EAAE;QACF,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE;KACpB,CAAC;IACF,MAAM,KAAK,GAAiB,EAAE,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;QAClE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;QAC/F,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,YAAY,IAAI,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO;QACL,cAAc,EAAE,cAAc;QAC9B,EAAE,EAAE,YAAY,CAAC,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACvE,IAAI,EAAE,aAAa;QACnB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,KAAK;QACL,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;QACzB,UAAU,EAAE,MAAM,EAAE;KACrB,CAAC;AACJ,CAAC"}
|
|
@@ -1,252 +0,0 @@
|
|
|
1
|
-
export interface ChatGptBrowserOptions {
|
|
2
|
-
port?: number;
|
|
3
|
-
profileDir?: string;
|
|
4
|
-
url?: string;
|
|
5
|
-
}
|
|
6
|
-
export interface ChatGptBrowserLaunch {
|
|
7
|
-
command: string;
|
|
8
|
-
args: string[];
|
|
9
|
-
profileDir: string;
|
|
10
|
-
port: number;
|
|
11
|
-
waitForEarlyExit: (timeoutMs?: number) => Promise<ChatGptBrowserEarlyExit | undefined>;
|
|
12
|
-
}
|
|
13
|
-
export interface ChatGptBrowserEarlyExit {
|
|
14
|
-
code?: number | null;
|
|
15
|
-
signal?: NodeJS.Signals | null;
|
|
16
|
-
error?: string;
|
|
17
|
-
}
|
|
18
|
-
export interface ChatGptBrowserStatus {
|
|
19
|
-
reachable: boolean;
|
|
20
|
-
loggedInLikely: boolean;
|
|
21
|
-
hasComposer: boolean;
|
|
22
|
-
visibilityState?: string;
|
|
23
|
-
url?: string;
|
|
24
|
-
title?: string;
|
|
25
|
-
modelHints: string[];
|
|
26
|
-
blocker?: {
|
|
27
|
-
code: string;
|
|
28
|
-
message: string;
|
|
29
|
-
retryable: boolean;
|
|
30
|
-
next_step?: string;
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
export declare class ChatGptBrowserBlockerError extends Error {
|
|
34
|
-
readonly blocker: NonNullable<ChatGptBrowserStatus["blocker"]>;
|
|
35
|
-
constructor(blocker: NonNullable<ChatGptBrowserStatus["blocker"]>);
|
|
36
|
-
}
|
|
37
|
-
export type ChatGptReasoningEffort = "즉시" | "중간" | "높음" | "매우 높음";
|
|
38
|
-
export type ChatGptProMode = "기본" | "확장";
|
|
39
|
-
/** Normalize a CLI reasoning-effort value onto the exact ChatGPT menu label. */
|
|
40
|
-
export declare function parseReasoningEffort(raw: string): ChatGptReasoningEffort;
|
|
41
|
-
/** Normalize a CLI Pro sub-mode value onto the exact ChatGPT menu label. */
|
|
42
|
-
export declare function parseProMode(raw: string): ChatGptProMode;
|
|
43
|
-
export declare const DEFAULT_CDP_PORT = 9333;
|
|
44
|
-
/**
|
|
45
|
-
* Stability policy for the answer poll loop. Returns true once the observed
|
|
46
|
-
* (answer, generating) stream should be accepted as final:
|
|
47
|
-
* - normal answers: two consecutive identical, non-generating polls;
|
|
48
|
-
* - answers whose tail looks like the streaming caret: six additional
|
|
49
|
-
* confirmations (~6s at the 1s poll cadence), so a lingering caret gets
|
|
50
|
-
* dropped by ChatGPT's finalization re-render first, while an answer that
|
|
51
|
-
* genuinely ends with an underscore is still accepted after the extra wait.
|
|
52
|
-
*/
|
|
53
|
-
export declare function createChatGptAnswerStabilityTracker(): (answer: string, generating: boolean) => boolean;
|
|
54
|
-
/**
|
|
55
|
-
* Resolve the Chrome DevTools port: explicit flag > PRODEX_CDP_PORT env >
|
|
56
|
-
* default 9333. The env var exists so a non-default port picked at login does
|
|
57
|
-
* not have to be repeated as --port on every later command.
|
|
58
|
-
*/
|
|
59
|
-
export declare function resolveCdpPort(explicit?: number): number;
|
|
60
|
-
export type SendChatGptProgressPhase = "connecting" | "tab_ready" | "selecting" | "sent" | "waiting" | "answered";
|
|
61
|
-
export interface SendChatGptProgressEvent {
|
|
62
|
-
phase: SendChatGptProgressPhase;
|
|
63
|
-
elapsedMs: number;
|
|
64
|
-
detail?: string;
|
|
65
|
-
}
|
|
66
|
-
export interface SendChatGptPromptOptions {
|
|
67
|
-
port?: number;
|
|
68
|
-
prompt: string;
|
|
69
|
-
targetUrl?: string;
|
|
70
|
-
timeoutMs?: number;
|
|
71
|
-
/** Switch into this sidebar project (by visible name) before sending. */
|
|
72
|
-
project?: string;
|
|
73
|
-
/** Create a new project with this name before sending. */
|
|
74
|
-
projectNew?: string;
|
|
75
|
-
/** Model to select in the composer picker, e.g. "Pro" or "GPT-5.5". */
|
|
76
|
-
model?: string;
|
|
77
|
-
/** Pro sub-mode, used when model is Pro. */
|
|
78
|
-
proMode?: ChatGptProMode;
|
|
79
|
-
/** Reasoning effort, used for non-Pro models. */
|
|
80
|
-
effort?: ChatGptReasoningEffort;
|
|
81
|
-
/**
|
|
82
|
-
* Navigate the tab to a fresh chat (chatgpt.com root) before sending. Long
|
|
83
|
-
* accumulated threads eventually break prompt-acceptance detection
|
|
84
|
-
* (measured live), so agent loops and debates should send each consult
|
|
85
|
-
* into a fresh chat. Incompatible with targetUrl.
|
|
86
|
-
*/
|
|
87
|
-
newChat?: boolean;
|
|
88
|
-
/** Progress callback so long sends can report phase + elapsed instead of staying silent. */
|
|
89
|
-
onProgress?: (event: SendChatGptProgressEvent) => void;
|
|
90
|
-
}
|
|
91
|
-
export interface SendChatGptPromptResult {
|
|
92
|
-
url: string;
|
|
93
|
-
title: string;
|
|
94
|
-
answer: string;
|
|
95
|
-
modelHints: string[];
|
|
96
|
-
warnings: string[];
|
|
97
|
-
}
|
|
98
|
-
interface ChatGptAnswerState {
|
|
99
|
-
title: string;
|
|
100
|
-
url: string;
|
|
101
|
-
answer: string;
|
|
102
|
-
modelHints: string[];
|
|
103
|
-
generating: boolean;
|
|
104
|
-
assistantMessageCount: number;
|
|
105
|
-
userMessageCount: number;
|
|
106
|
-
textSample: string;
|
|
107
|
-
blockerTextSample: string;
|
|
108
|
-
blockerScanTextSample?: string;
|
|
109
|
-
visibleButtonLabels: string[];
|
|
110
|
-
}
|
|
111
|
-
export interface ChatGptPageTextState {
|
|
112
|
-
textSample: string;
|
|
113
|
-
blockerTextSample?: string;
|
|
114
|
-
blockerScanTextSample?: string;
|
|
115
|
-
visibleButtonLabels: string[];
|
|
116
|
-
}
|
|
117
|
-
export declare const CHATGPT_RUNTIME_BLOCKER_TEXT_EXCLUDED_ANCESTORS = "[data-message-author-role],script,style,noscript,[aria-hidden=\"true\"],div[role=\"textbox\"],textarea,[contenteditable=\"true\"]";
|
|
118
|
-
export declare const CHATGPT_BLOCKER_SCAN_EXCLUDED_ANCESTORS = "[data-message-author-role],script,style,noscript,[aria-hidden=\"true\"],div[role=\"textbox\"],textarea,[contenteditable=\"true\"],nav,aside,[role=\"navigation\"]";
|
|
119
|
-
export declare const CHATGPT_COMPOSER_CANDIDATE_EXCLUDED_ANCESTORS = "[data-message-author-role],script,style,noscript,[aria-hidden=\"true\"]";
|
|
120
|
-
export declare const PRODEX_ACTIVE_COMPOSER_ATTRIBUTE = "data-prodex-active-composer";
|
|
121
|
-
export interface DevtoolsPage {
|
|
122
|
-
id?: string;
|
|
123
|
-
type: string;
|
|
124
|
-
url: string;
|
|
125
|
-
title: string;
|
|
126
|
-
webSocketDebuggerUrl: string;
|
|
127
|
-
}
|
|
128
|
-
export declare const CHATGPT_STREAMING_SELECTOR = "[data-testid=\"stop-button\"],[data-message-author-role=\"assistant\"][aria-busy=\"true\"],[data-message-author-role=\"assistant\"] [aria-busy=\"true\"]";
|
|
129
|
-
export declare function defaultChatGptProfileDir(): string;
|
|
130
|
-
export interface BrowserLoginLaunchRecord {
|
|
131
|
-
profile_dir: string;
|
|
132
|
-
port: number;
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Remember how the last login launched the browser (profile dir + port) so
|
|
136
|
-
* auto-recovery relaunches the SAME profile instead of the default one - a
|
|
137
|
-
* custom-profile user must never be silently sent to a different account.
|
|
138
|
-
* Best-effort: failures never break the login.
|
|
139
|
-
*/
|
|
140
|
-
export declare function recordBrowserLoginLaunch(record: BrowserLoginLaunchRecord): Promise<void>;
|
|
141
|
-
export declare function readLastBrowserLoginLaunch(): Promise<Partial<BrowserLoginLaunchRecord> | undefined>;
|
|
142
|
-
export declare function buildChromeLaunchArgs(options: Required<ChatGptBrowserOptions>): string[];
|
|
143
|
-
export declare function inferLoggedInLikely(text: string, visibleButtonLabels?: string[]): boolean;
|
|
144
|
-
export declare function isUsableChatGptAnswer(answer: string): boolean;
|
|
145
|
-
export declare function hasFreshChatGptAnswer(previousAssistantMessageCount: number, state: Pick<ChatGptAnswerState, "answer" | "assistantMessageCount" | "generating">): boolean;
|
|
146
|
-
export interface AcceptanceTimeoutContext {
|
|
147
|
-
timeoutMs: number;
|
|
148
|
-
composerStillHasText: boolean;
|
|
149
|
-
submitButtonFound: boolean;
|
|
150
|
-
}
|
|
151
|
-
export declare function acceptanceTimeoutError(ctx: AcceptanceTimeoutContext): Error;
|
|
152
|
-
export declare function hasPartialChatGptAnswer(previousAssistantMessageCount: number, state: Pick<ChatGptAnswerState, "answer" | "assistantMessageCount">): boolean;
|
|
153
|
-
/**
|
|
154
|
-
* True when the tab is on a fresh, empty ChatGPT chat: the root URL (not a
|
|
155
|
-
* /c/<id> conversation) with zero messages. Used after a --new-chat navigation
|
|
156
|
-
* to confirm the page actually reached the fresh chat before the answer-count
|
|
157
|
-
* baseline is captured - a lingering old thread (slow navigation) has a /c/ URL
|
|
158
|
-
* or non-zero counts and would poison the baseline.
|
|
159
|
-
*/
|
|
160
|
-
export declare function isFreshChatGptPage(state: {
|
|
161
|
-
url: string;
|
|
162
|
-
assistantMessageCount: number;
|
|
163
|
-
userMessageCount: number;
|
|
164
|
-
}): boolean;
|
|
165
|
-
export declare function hasChatGptPromptAcceptance(previous: Pick<ChatGptAnswerState, "assistantMessageCount" | "userMessageCount">, state: Pick<ChatGptAnswerState, "assistantMessageCount" | "generating" | "userMessageCount">): boolean;
|
|
166
|
-
export declare function chatGptBusyBlocker(generating: boolean): ChatGptBrowserStatus["blocker"] | undefined;
|
|
167
|
-
export declare function isLikelyChatGptSubmitButton(label: string, dataTestId: string | null): boolean;
|
|
168
|
-
export declare function isLikelyChatGptGeneratingControl(label: string): boolean;
|
|
169
|
-
export declare function detectChatGptBlocker(text: string, visibleButtonLabels?: string[]): ChatGptBrowserStatus["blocker"] | undefined;
|
|
170
|
-
export declare function detectChatGptPageBlocker(state: ChatGptPageTextState): ChatGptBrowserStatus["blocker"] | undefined;
|
|
171
|
-
export declare function inferChatGptPageLoggedInLikely(state: ChatGptPageTextState): boolean;
|
|
172
|
-
export declare function chatGptBlockerErrorFromAnswerState(state: {
|
|
173
|
-
textSample: string;
|
|
174
|
-
blockerTextSample?: string;
|
|
175
|
-
blockerScanTextSample?: string;
|
|
176
|
-
visibleButtonLabels: string[];
|
|
177
|
-
}): string | undefined;
|
|
178
|
-
export declare function chatGptBlockerFromAnswerState(state: {
|
|
179
|
-
textSample: string;
|
|
180
|
-
blockerTextSample?: string;
|
|
181
|
-
blockerScanTextSample?: string;
|
|
182
|
-
visibleButtonLabels: string[];
|
|
183
|
-
}): ChatGptBrowserStatus["blocker"] | undefined;
|
|
184
|
-
export declare function computePromptAcceptanceDeadline(timeoutMs: number, startedAt: number): number;
|
|
185
|
-
export declare function computePageDiscoveryTimeout(timeoutMs: number): number;
|
|
186
|
-
export declare function normalizeChatGptTargetUrl(value: string): string;
|
|
187
|
-
export declare function chatGptUrlsReferToSameTarget(currentUrl: string, expectedUrl: string): boolean;
|
|
188
|
-
export declare function selectChatGptPage(pages: DevtoolsPage[], targetUrl?: string, visibilityByPage?: Map<string, string>): DevtoolsPage | undefined;
|
|
189
|
-
export declare function chatGptPageSelectionBlocker(pages: DevtoolsPage[], targetUrl?: string, visibilityByPage?: Map<string, string>): ChatGptBrowserStatus["blocker"] | undefined;
|
|
190
|
-
export declare function assertVisibleChatGptTab(visibilityState: string | undefined, url: string, targetUrl?: string): void;
|
|
191
|
-
export declare function isTabActivationEnabled(env?: NodeJS.ProcessEnv): boolean;
|
|
192
|
-
export declare function assertChatGptTargetUrlMatches(currentUrl: string, targetUrl: string): void;
|
|
193
|
-
export declare function assertChatGptTargetTabAvailable(targetUrl: string): void;
|
|
194
|
-
export declare function assertChatGptPageAvailable(): never;
|
|
195
|
-
export declare function assertChatGptReadyForPrompt(loggedInLikely: boolean, hasComposer: boolean): void;
|
|
196
|
-
export declare function chatGptVisibilityBlocker(visibilityState: string | undefined, url: string | undefined): ChatGptBrowserStatus["blocker"] | undefined;
|
|
197
|
-
/**
|
|
198
|
-
* Environment for the browser spawn. On Linux shells without DISPLAY or
|
|
199
|
-
* WAYLAND_DISPLAY (common in WSL where a non-login shell does not export
|
|
200
|
-
* them), a present WSLg X socket means a desktop is actually available -
|
|
201
|
-
* inject DISPLAY=:0 so Chrome does not exit immediately with code 1.
|
|
202
|
-
*/
|
|
203
|
-
export declare function browserLaunchEnv(platform?: NodeJS.Platform, env?: Record<string, string | undefined>, hasX0Socket?: () => boolean): Record<string, string | undefined>;
|
|
204
|
-
export declare function openChatGptBrowser(options?: ChatGptBrowserOptions): ChatGptBrowserLaunch;
|
|
205
|
-
export declare function getChatGptBrowserStatus(options?: {
|
|
206
|
-
port?: number;
|
|
207
|
-
timeoutMs?: number;
|
|
208
|
-
}): Promise<ChatGptBrowserStatus>;
|
|
209
|
-
export declare function menuOpenExpression(): string;
|
|
210
|
-
export declare function menuClosedExpression(): string;
|
|
211
|
-
export declare function menuItemLabelMatches(text: string, candidates: readonly string[]): boolean;
|
|
212
|
-
export declare function menuItemPresentExpression(label: string | readonly string[]): string;
|
|
213
|
-
export declare function modelButtonRectExpression(): string;
|
|
214
|
-
export declare function menuItemRectExpression(label: string | readonly string[]): string;
|
|
215
|
-
export declare function submenuItemRectExpression(label: string | readonly string[]): string;
|
|
216
|
-
export declare function proRadioRectExpression(): string;
|
|
217
|
-
export declare function proSubmenuExpanderRectExpression(): string;
|
|
218
|
-
export declare function projectItemRectExpression(name: string): string;
|
|
219
|
-
export declare function newProjectButtonRectExpression(): string;
|
|
220
|
-
export declare function newProjectNameInputRectExpression(): string;
|
|
221
|
-
export declare function newProjectNameInputVisibleExpression(): string;
|
|
222
|
-
export declare function sendChatGptPrompt(options: SendChatGptPromptOptions): Promise<SendChatGptPromptResult>;
|
|
223
|
-
export interface ChatGptModelOption {
|
|
224
|
-
label: string;
|
|
225
|
-
kind: "radio" | "submenu";
|
|
226
|
-
checked: boolean;
|
|
227
|
-
}
|
|
228
|
-
export interface ListChatGptModelOptionsResult {
|
|
229
|
-
url: string;
|
|
230
|
-
options: ChatGptModelOption[];
|
|
231
|
-
}
|
|
232
|
-
export declare function modelMenuOptionsExpression(): string;
|
|
233
|
-
export declare function listChatGptModelOptions(input?: {
|
|
234
|
-
port?: number;
|
|
235
|
-
timeoutMs?: number;
|
|
236
|
-
}): Promise<ListChatGptModelOptionsResult>;
|
|
237
|
-
export declare function resolveCdpTimeoutMs(explicit?: number): number;
|
|
238
|
-
export declare const CHATGPT_THINKING_PLACEHOLDER_JS = "ansLines.length <= 1 && (/^(\uC0DD\uAC01\\s*\uC911|thinking)$/i.test(ansStripped) || /^thought (for|about)\\b.*$/i.test(ansStripped) || /\\d+\\s*s\\s*\uB3D9\uC548\\s*\uC0DD\uAC01\uD568$/.test(ansStripped) || /(^|\\s)(\uC0DD\uAC01\\s*\uC911|thinking)$/i.test(ansStripped))";
|
|
239
|
-
export declare function statusExpression(): string;
|
|
240
|
-
export declare function prepareComposerExpression(): string;
|
|
241
|
-
export declare function composerTextStateExpression(expectedText?: string): string;
|
|
242
|
-
export declare function submitExpression(): string;
|
|
243
|
-
/**
|
|
244
|
-
* Ordered browser candidates for the current platform: PATH binary names
|
|
245
|
-
* first, then well-known absolute install locations (macOS app bundles,
|
|
246
|
-
* Windows Program Files/LOCALAPPDATA, and Windows-host browsers under WSL).
|
|
247
|
-
* WSL detection cannot rely on WSL_DISTRO_NAME alone: non-login shells
|
|
248
|
-
* (measured live) may not carry it, so WSL_INTEROP and the kernel string are
|
|
249
|
-
* probed too.
|
|
250
|
-
*/
|
|
251
|
-
export declare function chromeCommandCandidates(platform?: NodeJS.Platform, env?: Record<string, string | undefined>, isWsl?: () => boolean): string[];
|
|
252
|
-
export {};
|