opendevbrowser 0.0.26 → 0.0.28
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 +7 -10
- package/dist/browser/canvas-manager.d.ts.map +1 -1
- package/dist/canvas/document-store.d.ts.map +1 -1
- package/dist/canvas/guidance.d.ts +22 -0
- package/dist/canvas/guidance.d.ts.map +1 -0
- package/dist/canvas/types.d.ts +3 -0
- package/dist/canvas/types.d.ts.map +1 -1
- package/dist/{chunk-GTTYIAI7.js → chunk-I5ZCOZZV.js} +316 -94
- package/dist/chunk-I5ZCOZZV.js.map +1 -0
- package/dist/{chunk-AVQL6WAS.js → chunk-T3VVHJTK.js} +2384 -544
- package/dist/chunk-T3VVHJTK.js.map +1 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/commands/daemon.d.ts +2 -0
- package/dist/cli/commands/daemon.d.ts.map +1 -1
- package/dist/cli/commands/devtools/console-poll.d.ts.map +1 -1
- package/dist/cli/commands/devtools/network-poll.d.ts.map +1 -1
- package/dist/cli/commands/inspiredesign.d.ts +2 -0
- package/dist/cli/commands/inspiredesign.d.ts.map +1 -1
- package/dist/cli/commands/macro-resolve.d.ts +2 -0
- package/dist/cli/commands/macro-resolve.d.ts.map +1 -1
- package/dist/cli/commands/product-video.d.ts +2 -0
- package/dist/cli/commands/product-video.d.ts.map +1 -1
- package/dist/cli/commands/research.d.ts +2 -0
- package/dist/cli/commands/research.d.ts.map +1 -1
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/daemon-autostart.d.ts +6 -2
- package/dist/cli/daemon-autostart.d.ts.map +1 -1
- package/dist/cli/daemon-commands.d.ts.map +1 -1
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/index.js +516 -86
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/utils/parse.d.ts.map +1 -1
- package/dist/cli/utils/workflow-message.d.ts +3 -0
- package/dist/cli/utils/workflow-message.d.ts.map +1 -1
- package/dist/daemon-fingerprint.json +1 -1
- package/dist/index.js +39 -15
- package/dist/index.js.map +1 -1
- package/dist/inspiredesign/brief-expansion.d.ts +3 -0
- package/dist/inspiredesign/brief-expansion.d.ts.map +1 -1
- package/dist/{providers/inspiredesign-capture-mode.d.ts → inspiredesign/capture-mode.d.ts} +2 -2
- package/dist/inspiredesign/capture-mode.d.ts.map +1 -0
- package/dist/{providers/inspiredesign-capture.d.ts → inspiredesign/capture.d.ts} +3 -3
- package/dist/inspiredesign/capture.d.ts.map +1 -0
- package/dist/{providers/inspiredesign-contract.d.ts → inspiredesign/contract.d.ts} +70 -6
- package/dist/inspiredesign/contract.d.ts.map +1 -0
- package/dist/inspiredesign/handoff.d.ts +12 -10
- package/dist/inspiredesign/handoff.d.ts.map +1 -1
- package/dist/inspiredesign/reference-pattern-board.d.ts +74 -0
- package/dist/inspiredesign/reference-pattern-board.d.ts.map +1 -0
- package/dist/macros/execute-runtime.d.ts +2 -1
- package/dist/macros/execute-runtime.d.ts.map +1 -1
- package/dist/macros/execute.d.ts +4 -2
- package/dist/macros/execute.d.ts.map +1 -1
- package/dist/opendevbrowser.js +39 -15
- package/dist/opendevbrowser.js.map +1 -1
- package/dist/providers/browser-fallback.d.ts +7 -0
- package/dist/providers/browser-fallback.d.ts.map +1 -1
- package/dist/providers/community/index.d.ts.map +1 -1
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/renderer.d.ts +1 -1
- package/dist/providers/renderer.d.ts.map +1 -1
- package/dist/providers/research-compiler.d.ts.map +1 -1
- package/dist/providers/runtime-bundle.d.ts +1 -1
- package/dist/providers/runtime-bundle.d.ts.map +1 -1
- package/dist/providers/runtime-factory.d.ts.map +1 -1
- package/dist/providers/shopping/index.d.ts.map +1 -1
- package/dist/providers/social/platform.d.ts.map +1 -1
- package/dist/providers/social/search-quality.d.ts.map +1 -1
- package/dist/providers/social/youtube.d.ts.map +1 -1
- package/dist/providers/workflow-handoff.d.ts +18 -1
- package/dist/providers/workflow-handoff.d.ts.map +1 -1
- package/dist/providers/workflows.d.ts +10 -5
- package/dist/providers/workflows.d.ts.map +1 -1
- package/dist/{providers-T2FQJCF6.js → providers-QF2RFB4J.js} +2 -2
- package/dist/public-surface/generated-manifest.d.ts +8 -8
- package/dist/public-surface/generated-manifest.d.ts.map +1 -1
- package/dist/public-surface/source.d.ts +13 -12
- package/dist/public-surface/source.d.ts.map +1 -1
- package/dist/relay/protocol.d.ts +14 -2
- package/dist/relay/protocol.d.ts.map +1 -1
- package/dist/tools/inspiredesign_run.d.ts.map +1 -1
- package/dist/tools/macro_resolve.d.ts.map +1 -1
- package/dist/tools/product_video_run.d.ts.map +1 -1
- package/dist/tools/research_run.d.ts.map +1 -1
- package/dist/tools/shopping_run.d.ts.map +1 -1
- package/extension/dist/canvas/canvas-runtime.js +13 -6
- package/extension/dist/services/ConnectionManager.js +8 -4
- package/extension/manifest.json +1 -1
- package/package.json +1 -1
- package/skills/opendevbrowser-best-practices/SKILL.md +6 -6
- package/skills/opendevbrowser-best-practices/assets/templates/skill-runtime-pack-matrix.json +1 -1
- package/skills/opendevbrowser-design-agent/SKILL.md +5 -0
- package/skills/opendevbrowser-design-agent/artifacts/design-contract-playbook.md +6 -1
- package/skills/opendevbrowser-design-agent/assets/templates/design-contract.v1.json +15 -1
- package/skills/opendevbrowser-design-agent/assets/templates/inspiredesign-advanced-brief.v1.json +72 -33
- package/skills/opendevbrowser-design-agent/assets/templates/reference-pattern-board.v1.json +2 -0
- package/dist/chunk-AVQL6WAS.js.map +0 -1
- package/dist/chunk-GTTYIAI7.js.map +0 -1
- package/dist/providers/inspiredesign-capture-mode.d.ts.map +0 -1
- package/dist/providers/inspiredesign-capture.d.ts.map +0 -1
- package/dist/providers/inspiredesign-contract.d.ts.map +0 -1
- /package/dist/{providers-T2FQJCF6.js.map → providers-QF2RFB4J.js.map} +0 -0
package/dist/cli/index.js
CHANGED
|
@@ -41,7 +41,7 @@ import {
|
|
|
41
41
|
resolveExitCode,
|
|
42
42
|
startDaemon,
|
|
43
43
|
toCliError
|
|
44
|
-
} from "../chunk-
|
|
44
|
+
} from "../chunk-I5ZCOZZV.js";
|
|
45
45
|
import "../chunk-STGGGVYT.js";
|
|
46
46
|
import {
|
|
47
47
|
createNoOpSkillRemovalResult,
|
|
@@ -74,7 +74,7 @@ import {
|
|
|
74
74
|
setDefaultLogSink,
|
|
75
75
|
stderrSink,
|
|
76
76
|
summarizePrimaryProviderIssue
|
|
77
|
-
} from "../chunk-
|
|
77
|
+
} from "../chunk-T3VVHJTK.js";
|
|
78
78
|
import "../chunk-FUSXMW3G.js";
|
|
79
79
|
|
|
80
80
|
// src/cli/args.ts
|
|
@@ -143,6 +143,17 @@ function parseTransport(args) {
|
|
|
143
143
|
}
|
|
144
144
|
var VALID_FLAG_SET = new Set(VALID_FLAGS);
|
|
145
145
|
var VALID_EQUALS_FLAG_SET = new Set(VALID_EQUALS_FLAGS);
|
|
146
|
+
var SIGNED_VALUE_FLAG_SET = /* @__PURE__ */ new Set(["--dy"]);
|
|
147
|
+
var SIGNED_INTEGER_VALUE = /^-\d+$/;
|
|
148
|
+
function shouldSkipValueToken(flag, value) {
|
|
149
|
+
if (!VALID_EQUALS_FLAG_SET.has(flag) || value === void 0) {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
if (!value.startsWith("-")) {
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
return SIGNED_VALUE_FLAG_SET.has(flag) && SIGNED_INTEGER_VALUE.test(value);
|
|
156
|
+
}
|
|
146
157
|
function parseArgs(argv) {
|
|
147
158
|
let args = expandShortFlags(argv.slice(2));
|
|
148
159
|
let commandOverride = null;
|
|
@@ -237,7 +248,8 @@ function parseArgs(argv) {
|
|
|
237
248
|
} else if (noPrompt) {
|
|
238
249
|
mode = "global";
|
|
239
250
|
}
|
|
240
|
-
for (
|
|
251
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
252
|
+
const arg = args[index] ?? "";
|
|
241
253
|
if (arg.startsWith("--") && !VALID_FLAG_SET.has(arg)) {
|
|
242
254
|
if (arg.includes("=")) {
|
|
243
255
|
const baseFlag = arg.split("=", 2)[0] ?? "";
|
|
@@ -250,6 +262,9 @@ function parseArgs(argv) {
|
|
|
250
262
|
if (arg.startsWith("-") && !arg.startsWith("--") && !SHORT_FLAGS[arg]) {
|
|
251
263
|
throw createUsageError(`Unknown flag: ${arg}`);
|
|
252
264
|
}
|
|
265
|
+
if (shouldSkipValueToken(arg, args[index + 1])) {
|
|
266
|
+
index += 1;
|
|
267
|
+
}
|
|
253
268
|
}
|
|
254
269
|
return {
|
|
255
270
|
command: commandOverride ?? "install",
|
|
@@ -441,7 +456,7 @@ var HELP_FLAG_GROUPS = [
|
|
|
441
456
|
{ flag: "--include-all-images", description: "Include all discovered product images." },
|
|
442
457
|
{ flag: "--include-copy", description: "Include product marketing copy metadata." },
|
|
443
458
|
{ flag: "--use-cookies", description: "Enable or disable provider cookie injection for workflow runs; a bare flag means true.", example: "opendevbrowser shopping run --query 'usb hub' --use-cookies" },
|
|
444
|
-
{ flag: "--browser-mode", description: "
|
|
459
|
+
{ flag: "--browser-mode", description: "Provider browser transport mode: auto, extension, or managed. extension reuses relay-backed signed-in browser state; managed runs a deterministic managed browser.", example: "opendevbrowser research run --topic 'browser automation on X' --source-selection social --browser-mode extension --use-cookies --challenge-automation-mode browser_with_helper" },
|
|
445
460
|
{ flag: "--challenge-automation-mode", description: "Per-run challenge automation mode for workflow runs and macro-resolve execute: off, browser, or browser_with_helper. Precedence is run > session > config, and the helper remains browser-scoped only.", example: `opendevbrowser macro-resolve --expression '@community.search("openai")' --execute --challenge-automation-mode browser_with_helper` },
|
|
446
461
|
{ flag: "--cookie-policy-override", description: "Per-run workflow cookie policy override: off, auto, or required.", example: "opendevbrowser research run --topic 'agent workflows' --cookie-policy-override required" },
|
|
447
462
|
{ flag: "--cookie-policy", description: "Alias of --cookie-policy-override." },
|
|
@@ -554,6 +569,7 @@ var HELP_ONBOARDING_ENTRIES = [
|
|
|
554
569
|
];
|
|
555
570
|
var HELP_REFERENCE_ENTRIES = [
|
|
556
571
|
{ label: "src/cli/onboarding-metadata.json", description: "Canonical first-contact onboarding metadata shared by help, nudges, and proof lanes." },
|
|
572
|
+
{ label: "src/providers/workflow-handoff.ts", description: "Central next-step advisory builders for workflow follow-through." },
|
|
557
573
|
{ label: "src/inspiredesign/handoff.ts", description: "Shared inspiredesign follow-through commands, artifact names, and Canvas continuation guidance." },
|
|
558
574
|
{ label: "src/public-surface/source.ts", description: "Authoritative command, usage, flag, and tool surface metadata." },
|
|
559
575
|
{ label: "src/public-surface/generated-manifest.ts", description: "Checked-in generated public-surface snapshot consumed by help and parity tests." },
|
|
@@ -929,45 +945,292 @@ function installLocal(withConfig = false) {
|
|
|
929
945
|
import * as fs4 from "fs";
|
|
930
946
|
import * as path2 from "path";
|
|
931
947
|
import * as os2 from "os";
|
|
948
|
+
import { randomUUID } from "crypto";
|
|
932
949
|
var PLUGIN_NAME = "opendevbrowser";
|
|
950
|
+
var CACHE_MANIFEST = "package.json";
|
|
951
|
+
var CACHE_LOCKFILE = "package-lock.json";
|
|
952
|
+
var CACHE_UPDATE_LOCK = ".opendevbrowser-update.lock";
|
|
953
|
+
var CACHE_LOCK_STALE_MS = 30 * 60 * 1e3;
|
|
954
|
+
var DEPENDENCY_SECTIONS = [
|
|
955
|
+
"dependencies",
|
|
956
|
+
"devDependencies",
|
|
957
|
+
"optionalDependencies",
|
|
958
|
+
"peerDependencies"
|
|
959
|
+
];
|
|
933
960
|
function getCacheDir() {
|
|
934
961
|
return process.env.OPENCODE_CACHE_DIR || path2.join(os2.homedir(), ".cache", "opencode");
|
|
935
962
|
}
|
|
936
|
-
function
|
|
937
|
-
const cacheDir = getCacheDir();
|
|
963
|
+
function assertCacheChild(targetPath, cacheDir) {
|
|
938
964
|
const resolvedCache = path2.resolve(cacheDir);
|
|
939
|
-
const resolvedPath = path2.resolve(
|
|
940
|
-
|
|
941
|
-
|
|
965
|
+
const resolvedPath = path2.resolve(targetPath);
|
|
966
|
+
const relativePath = path2.relative(resolvedCache, resolvedPath);
|
|
967
|
+
if (!relativePath || relativePath.startsWith("..") || path2.isAbsolute(relativePath)) {
|
|
968
|
+
throw new Error(`Security: refusing to modify path outside cache directory: ${targetPath}`);
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
function isMissingPathError(error) {
|
|
972
|
+
return error instanceof Error && "code" in error && error.code === "ENOENT";
|
|
973
|
+
}
|
|
974
|
+
function isExistingPathError(error) {
|
|
975
|
+
return error instanceof Error && "code" in error && error.code === "EEXIST";
|
|
976
|
+
}
|
|
977
|
+
function assertNoSymlinkCachePath(targetPath, cacheDir) {
|
|
978
|
+
assertCacheChild(targetPath, cacheDir);
|
|
979
|
+
const resolvedCache = path2.resolve(cacheDir);
|
|
980
|
+
const relativeSegments = path2.relative(resolvedCache, path2.resolve(targetPath)).split(path2.sep).filter(Boolean);
|
|
981
|
+
for (const candidate of [resolvedCache, ...relativeSegments.map((_, index) => path2.join(resolvedCache, ...relativeSegments.slice(0, index + 1)))]) {
|
|
982
|
+
try {
|
|
983
|
+
if (fs4.lstatSync(candidate).isSymbolicLink()) {
|
|
984
|
+
throw new Error(`Security: refusing to modify symlinked cache path: ${candidate}`);
|
|
985
|
+
}
|
|
986
|
+
} catch (error) {
|
|
987
|
+
if (isMissingPathError(error)) {
|
|
988
|
+
continue;
|
|
989
|
+
}
|
|
990
|
+
throw error;
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
function cacheDirectoryExists(cacheDir) {
|
|
995
|
+
try {
|
|
996
|
+
const stat = fs4.lstatSync(cacheDir);
|
|
997
|
+
if (stat.isSymbolicLink()) {
|
|
998
|
+
throw new Error(`Security: refusing to modify symlinked cache path: ${cacheDir}`);
|
|
999
|
+
}
|
|
1000
|
+
if (!stat.isDirectory()) {
|
|
1001
|
+
throw new Error(`${cacheDir} must be a directory`);
|
|
1002
|
+
}
|
|
1003
|
+
return true;
|
|
1004
|
+
} catch (error) {
|
|
1005
|
+
if (isMissingPathError(error)) {
|
|
1006
|
+
return false;
|
|
1007
|
+
}
|
|
1008
|
+
throw error;
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
function removePathIfExists(targetPath, cacheDir) {
|
|
1012
|
+
assertNoSymlinkCachePath(targetPath, cacheDir);
|
|
1013
|
+
if (!fs4.existsSync(targetPath)) {
|
|
1014
|
+
return false;
|
|
1015
|
+
}
|
|
1016
|
+
fs4.rmSync(targetPath, { recursive: true, force: true });
|
|
1017
|
+
return true;
|
|
1018
|
+
}
|
|
1019
|
+
function cacheFileExists(targetPath, cacheDir) {
|
|
1020
|
+
assertNoSymlinkCachePath(targetPath, cacheDir);
|
|
1021
|
+
try {
|
|
1022
|
+
const stat = fs4.lstatSync(targetPath);
|
|
1023
|
+
if (stat.isSymbolicLink()) {
|
|
1024
|
+
throw new Error(`Security: refusing to modify symlinked cache manifest: ${targetPath}`);
|
|
1025
|
+
}
|
|
1026
|
+
return stat.isFile();
|
|
1027
|
+
} catch (error) {
|
|
1028
|
+
if (isMissingPathError(error)) {
|
|
1029
|
+
return false;
|
|
1030
|
+
}
|
|
1031
|
+
throw error;
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
function writeManifestAtomic(manifestPath, cacheDir, manifest) {
|
|
1035
|
+
const tempPath = `${manifestPath}.${process.pid}.tmp`;
|
|
1036
|
+
assertNoSymlinkCachePath(tempPath, cacheDir);
|
|
1037
|
+
let fd = null;
|
|
1038
|
+
try {
|
|
1039
|
+
fd = fs4.openSync(tempPath, "wx");
|
|
1040
|
+
fs4.writeFileSync(fd, `${JSON.stringify(manifest, null, 2)}
|
|
1041
|
+
`, "utf8");
|
|
1042
|
+
fs4.closeSync(fd);
|
|
1043
|
+
fd = null;
|
|
1044
|
+
fs4.renameSync(tempPath, manifestPath);
|
|
1045
|
+
} catch (error) {
|
|
1046
|
+
if (fd !== null) {
|
|
1047
|
+
fs4.closeSync(fd);
|
|
1048
|
+
}
|
|
1049
|
+
fs4.rmSync(tempPath, { force: true });
|
|
1050
|
+
throw error;
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
function withCacheMutationLock(cacheDir, action) {
|
|
1054
|
+
const lockPath = path2.join(cacheDir, CACHE_UPDATE_LOCK);
|
|
1055
|
+
assertNoSymlinkCachePath(lockPath, cacheDir);
|
|
1056
|
+
let lock = null;
|
|
1057
|
+
try {
|
|
1058
|
+
lock = openCacheMutationLock(lockPath);
|
|
1059
|
+
return action();
|
|
1060
|
+
} catch (error) {
|
|
1061
|
+
if (isExistingPathError(error)) {
|
|
1062
|
+
throw new Error("another update is already running for this OpenCode cache");
|
|
1063
|
+
}
|
|
1064
|
+
throw error;
|
|
1065
|
+
} finally {
|
|
1066
|
+
if (lock !== null) {
|
|
1067
|
+
fs4.closeSync(lock.fd);
|
|
1068
|
+
removeOwnedCacheMutationLock(lockPath, lock.token);
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
function openCacheMutationLock(lockPath) {
|
|
1073
|
+
try {
|
|
1074
|
+
return writeCacheMutationLock(lockPath);
|
|
1075
|
+
} catch (error) {
|
|
1076
|
+
if (!isExistingPathError(error) || !isStaleCacheMutationLock(lockPath)) {
|
|
1077
|
+
throw error;
|
|
1078
|
+
}
|
|
1079
|
+
removeStaleCacheMutationLock(lockPath);
|
|
1080
|
+
return writeCacheMutationLock(lockPath);
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
function writeCacheMutationLock(lockPath) {
|
|
1084
|
+
const fd = fs4.openSync(lockPath, "wx");
|
|
1085
|
+
const token = randomUUID();
|
|
1086
|
+
try {
|
|
1087
|
+
const lock = { pid: process.pid, createdAt: Date.now(), token };
|
|
1088
|
+
fs4.writeFileSync(fd, `${JSON.stringify(lock)}
|
|
1089
|
+
`, "utf8");
|
|
1090
|
+
return { fd, token };
|
|
1091
|
+
} catch (error) {
|
|
1092
|
+
fs4.closeSync(fd);
|
|
1093
|
+
fs4.rmSync(lockPath, { force: true });
|
|
1094
|
+
throw error;
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
function isStaleCacheMutationLock(lockPath) {
|
|
1098
|
+
const lock = readCacheMutationLock(lockPath);
|
|
1099
|
+
if (!lock) {
|
|
1100
|
+
return isLegacyCacheMutationLockStale(lockPath);
|
|
1101
|
+
}
|
|
1102
|
+
if (Date.now() - lock.createdAt < CACHE_LOCK_STALE_MS) {
|
|
1103
|
+
return false;
|
|
1104
|
+
}
|
|
1105
|
+
return !isProcessRunning(lock.pid);
|
|
1106
|
+
}
|
|
1107
|
+
function isLegacyCacheMutationLockStale(lockPath) {
|
|
1108
|
+
try {
|
|
1109
|
+
const pid = readLegacyCacheMutationLockPid(lockPath);
|
|
1110
|
+
if (pid !== null && isProcessRunning(pid)) {
|
|
1111
|
+
return false;
|
|
1112
|
+
}
|
|
1113
|
+
return Date.now() - fs4.statSync(lockPath).mtimeMs >= CACHE_LOCK_STALE_MS;
|
|
1114
|
+
} catch {
|
|
1115
|
+
return false;
|
|
942
1116
|
}
|
|
943
|
-
|
|
944
|
-
|
|
1117
|
+
}
|
|
1118
|
+
function readLegacyCacheMutationLockPid(lockPath) {
|
|
1119
|
+
const raw = fs4.readFileSync(lockPath, "utf8").trim();
|
|
1120
|
+
if (!/^\d+$/.test(raw)) {
|
|
1121
|
+
return null;
|
|
945
1122
|
}
|
|
1123
|
+
const pid = Number(raw);
|
|
1124
|
+
return Number.isSafeInteger(pid) && pid > 0 ? pid : null;
|
|
1125
|
+
}
|
|
1126
|
+
function readCacheMutationLock(lockPath) {
|
|
1127
|
+
try {
|
|
1128
|
+
const parsed = JSON.parse(fs4.readFileSync(lockPath, "utf8"));
|
|
1129
|
+
const { pid, createdAt, token } = parsed;
|
|
1130
|
+
const hasToken = token === void 0 || typeof token === "string" && token.length > 0;
|
|
1131
|
+
if (typeof pid === "number" && typeof createdAt === "number" && hasToken && Number.isInteger(pid) && Number.isFinite(createdAt)) {
|
|
1132
|
+
return token === void 0 ? { pid, createdAt } : { pid, createdAt, token };
|
|
1133
|
+
}
|
|
1134
|
+
} catch {
|
|
1135
|
+
return null;
|
|
1136
|
+
}
|
|
1137
|
+
return null;
|
|
1138
|
+
}
|
|
1139
|
+
function isProcessRunning(pid) {
|
|
1140
|
+
try {
|
|
1141
|
+
process.kill(pid, 0);
|
|
1142
|
+
return true;
|
|
1143
|
+
} catch (error) {
|
|
1144
|
+
return error instanceof Error && "code" in error && error.code === "EPERM";
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
function createExistingLockError() {
|
|
1148
|
+
const error = new Error("cache update lock changed before stale cleanup");
|
|
1149
|
+
error.code = "EEXIST";
|
|
1150
|
+
return error;
|
|
1151
|
+
}
|
|
1152
|
+
function removeStaleCacheMutationLock(lockPath) {
|
|
1153
|
+
const content = fs4.readFileSync(lockPath, "utf8");
|
|
1154
|
+
if (!isStaleCacheMutationLock(lockPath) || fs4.readFileSync(lockPath, "utf8") !== content) {
|
|
1155
|
+
throw createExistingLockError();
|
|
1156
|
+
}
|
|
1157
|
+
fs4.rmSync(lockPath, { force: true });
|
|
1158
|
+
}
|
|
1159
|
+
function removeOwnedCacheMutationLock(lockPath, token) {
|
|
1160
|
+
const lock = readCacheMutationLock(lockPath);
|
|
1161
|
+
if (lock?.token === token) {
|
|
1162
|
+
fs4.rmSync(lockPath, { force: true });
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
function preflightCacheMutationPaths(cacheDir, paths) {
|
|
1166
|
+
for (const targetPath of paths) {
|
|
1167
|
+
assertNoSymlinkCachePath(targetPath, cacheDir);
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
function isJsonObject(value) {
|
|
1171
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1172
|
+
}
|
|
1173
|
+
function removeDependencyPin(manifest, section) {
|
|
1174
|
+
const dependencies = manifest[section];
|
|
1175
|
+
if (!isJsonObject(dependencies) || !(PLUGIN_NAME in dependencies)) {
|
|
1176
|
+
return false;
|
|
1177
|
+
}
|
|
1178
|
+
delete dependencies[PLUGIN_NAME];
|
|
1179
|
+
if (Object.keys(dependencies).length === 0) {
|
|
1180
|
+
delete manifest[section];
|
|
1181
|
+
}
|
|
1182
|
+
return true;
|
|
1183
|
+
}
|
|
1184
|
+
function removeManifestPin(cacheDir) {
|
|
1185
|
+
const manifestPath = path2.join(cacheDir, CACHE_MANIFEST);
|
|
1186
|
+
if (!cacheFileExists(manifestPath, cacheDir)) {
|
|
1187
|
+
return false;
|
|
1188
|
+
}
|
|
1189
|
+
const manifest = JSON.parse(fs4.readFileSync(manifestPath, "utf8"));
|
|
1190
|
+
if (!isJsonObject(manifest)) {
|
|
1191
|
+
throw new Error(`${CACHE_MANIFEST} must contain a JSON object`);
|
|
1192
|
+
}
|
|
1193
|
+
const removed = DEPENDENCY_SECTIONS.map((section) => removeDependencyPin(manifest, section)).some(Boolean);
|
|
1194
|
+
if (removed) {
|
|
1195
|
+
writeManifestAtomic(manifestPath, cacheDir, manifest);
|
|
1196
|
+
}
|
|
1197
|
+
return removed;
|
|
946
1198
|
}
|
|
947
1199
|
function runUpdate() {
|
|
948
1200
|
const cacheDir = getCacheDir();
|
|
949
1201
|
const nodeModulesDir = path2.join(cacheDir, "node_modules");
|
|
950
1202
|
const pluginCacheDir = path2.join(nodeModulesDir, PLUGIN_NAME);
|
|
1203
|
+
const lockfilePath = path2.join(cacheDir, CACHE_LOCKFILE);
|
|
951
1204
|
try {
|
|
952
|
-
if (!
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
1205
|
+
if (!cacheDirectoryExists(cacheDir)) {
|
|
1206
|
+
return {
|
|
1207
|
+
success: true,
|
|
1208
|
+
message: "No cached plugin found. OpenCode will install the latest version on next run.",
|
|
1209
|
+
cleared: false
|
|
1210
|
+
};
|
|
1211
|
+
}
|
|
1212
|
+
preflightCacheMutationPaths(cacheDir, [
|
|
1213
|
+
path2.join(cacheDir, CACHE_MANIFEST),
|
|
1214
|
+
pluginCacheDir,
|
|
1215
|
+
lockfilePath,
|
|
1216
|
+
path2.join(cacheDir, CACHE_UPDATE_LOCK)
|
|
1217
|
+
]);
|
|
1218
|
+
const cleared = withCacheMutationLock(cacheDir, () => {
|
|
1219
|
+
const manifestPinRemoved = removeManifestPin(cacheDir);
|
|
1220
|
+
const packageRemoved = removePathIfExists(pluginCacheDir, cacheDir);
|
|
1221
|
+
const lockfileRemoved = removePathIfExists(lockfilePath, cacheDir);
|
|
1222
|
+
return packageRemoved || manifestPinRemoved || lockfileRemoved;
|
|
1223
|
+
});
|
|
1224
|
+
if (!cleared) {
|
|
961
1225
|
return {
|
|
962
1226
|
success: true,
|
|
963
1227
|
message: "No cached plugin found. OpenCode will install the latest version on next run.",
|
|
964
1228
|
cleared: false
|
|
965
1229
|
};
|
|
966
1230
|
}
|
|
967
|
-
rmdir(pluginCacheDir);
|
|
968
1231
|
return {
|
|
969
1232
|
success: true,
|
|
970
|
-
message: "Cache
|
|
1233
|
+
message: "Cache repaired. OpenCode will install the latest version on next run.",
|
|
971
1234
|
cleared: true
|
|
972
1235
|
};
|
|
973
1236
|
} catch (error) {
|
|
@@ -1056,7 +1319,24 @@ function findInstalledConfigs() {
|
|
|
1056
1319
|
import { spawnSync } from "child_process";
|
|
1057
1320
|
|
|
1058
1321
|
// src/cli/utils/parse.ts
|
|
1322
|
+
var SIGNED_INTEGER_PATTERN = /^-?\d+$/;
|
|
1323
|
+
var UNSIGNED_INTEGER_PATTERN = /^\d+$/;
|
|
1324
|
+
var SIGNED_DECIMAL_PATTERN = /^-?(?:\d+|\d+\.\d+|\.\d+)$/;
|
|
1325
|
+
var UNSIGNED_DECIMAL_PATTERN = /^(?:\d+|\d+\.\d+|\.\d+)$/;
|
|
1326
|
+
function allowsNegative(options) {
|
|
1327
|
+
return typeof options.min !== "number" || options.min < 0;
|
|
1328
|
+
}
|
|
1329
|
+
function decimalPattern(options) {
|
|
1330
|
+
const signed = allowsNegative(options);
|
|
1331
|
+
if (options.integer ?? true) {
|
|
1332
|
+
return signed ? SIGNED_INTEGER_PATTERN : UNSIGNED_INTEGER_PATTERN;
|
|
1333
|
+
}
|
|
1334
|
+
return signed ? SIGNED_DECIMAL_PATTERN : UNSIGNED_DECIMAL_PATTERN;
|
|
1335
|
+
}
|
|
1059
1336
|
function parseNumberFlag(value, flag, options = {}) {
|
|
1337
|
+
if (value.trim() === "" || value !== value.trim() || !decimalPattern(options).test(value)) {
|
|
1338
|
+
throw createUsageError(`Invalid ${flag}: ${value}`);
|
|
1339
|
+
}
|
|
1060
1340
|
const parsed = Number(value);
|
|
1061
1341
|
if (!Number.isFinite(parsed)) {
|
|
1062
1342
|
throw createUsageError(`Invalid ${flag}: ${value}`);
|
|
@@ -1927,9 +2207,9 @@ ${nativeMessage}${staleNote}` : `${baseMessage}${staleNote}`;
|
|
|
1927
2207
|
|
|
1928
2208
|
// src/cli/daemon-autostart.ts
|
|
1929
2209
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
1930
|
-
import { existsSync as existsSync5, mkdirSync as mkdirSync2, unlinkSync as unlinkSync2, writeFileSync as
|
|
2210
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync2, statSync as statSync2, unlinkSync as unlinkSync2, writeFileSync as writeFileSync5 } from "fs";
|
|
1931
2211
|
import { homedir as homedir4, tmpdir } from "os";
|
|
1932
|
-
import { dirname as dirname3, isAbsolute, join as join5, relative, resolve as resolve3 } from "path";
|
|
2212
|
+
import { dirname as dirname3, isAbsolute as isAbsolute2, join as join5, relative as relative2, resolve as resolve3 } from "path";
|
|
1933
2213
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1934
2214
|
var MAC_LABEL = "com.opendevbrowser.daemon";
|
|
1935
2215
|
var WIN_TASK_NAME = "OpenDevBrowser Daemon";
|
|
@@ -1942,7 +2222,8 @@ var defaultDeps = () => ({
|
|
|
1942
2222
|
homedir: homedir4,
|
|
1943
2223
|
existsSync: existsSync5,
|
|
1944
2224
|
mkdirSync: mkdirSync2,
|
|
1945
|
-
|
|
2225
|
+
statSync: statSync2,
|
|
2226
|
+
writeFileSync: writeFileSync5,
|
|
1946
2227
|
unlinkSync: unlinkSync2,
|
|
1947
2228
|
execFileSync: execFileSync2,
|
|
1948
2229
|
transientEntrypointRoots: void 0
|
|
@@ -1951,6 +2232,17 @@ var NPX_CACHE_SEGMENT_PATTERN = /[\\/]_npx(?:[\\/]|$)/;
|
|
|
1951
2232
|
var formatCommand = (programArguments) => {
|
|
1952
2233
|
return programArguments.map((value) => `"${value}"`).join(" ");
|
|
1953
2234
|
};
|
|
2235
|
+
var resolveMacWorkingDirectory = (home) => {
|
|
2236
|
+
return join5(home, ".cache", "opendevbrowser");
|
|
2237
|
+
};
|
|
2238
|
+
var pathIsDirectory = (path5, deps) => {
|
|
2239
|
+
if (!deps.existsSync(path5)) return false;
|
|
2240
|
+
try {
|
|
2241
|
+
return deps.statSync(path5).isDirectory();
|
|
2242
|
+
} catch {
|
|
2243
|
+
return false;
|
|
2244
|
+
}
|
|
2245
|
+
};
|
|
1954
2246
|
var resolveCliPathFromModule = (moduleUrl, exists) => {
|
|
1955
2247
|
const modulePath = fileURLToPath2(moduleUrl);
|
|
1956
2248
|
const candidate = resolve3(dirname3(modulePath), "..", "index.js");
|
|
@@ -1966,8 +2258,8 @@ var normalizeComparisonPath = (value, platform) => {
|
|
|
1966
2258
|
var isPathInsideRoot = (candidate, root, platform) => {
|
|
1967
2259
|
const normalizedCandidate = normalizeComparisonPath(candidate, platform);
|
|
1968
2260
|
const normalizedRoot = normalizeComparisonPath(root, platform);
|
|
1969
|
-
const relation =
|
|
1970
|
-
return relation === "" || !relation.startsWith("..") && !
|
|
2261
|
+
const relation = relative2(normalizedRoot, normalizedCandidate);
|
|
2262
|
+
return relation === "" || !relation.startsWith("..") && !isAbsolute2(relation);
|
|
1971
2263
|
};
|
|
1972
2264
|
var getTransientEntrypointRoots = (deps) => {
|
|
1973
2265
|
const configuredRoots = deps.transientEntrypointRoots;
|
|
@@ -2013,18 +2305,20 @@ var resolveCliEntrypoint = (deps = {}) => {
|
|
|
2013
2305
|
var getLaunchAgentPath = (home = homedir4()) => {
|
|
2014
2306
|
return join5(home, "Library", "LaunchAgents", `${MAC_LABEL}.plist`);
|
|
2015
2307
|
};
|
|
2308
|
+
var escapePlistString = (value) => value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
2016
2309
|
var buildLaunchAgentPlist = (entrypoint, options = {}) => {
|
|
2017
2310
|
const label = options.label ?? MAC_LABEL;
|
|
2018
2311
|
const stdoutPath = options.stdoutPath ?? join5(homedir4(), "Library", "Logs", "opendevbrowser-daemon.log");
|
|
2019
2312
|
const stderrPath = options.stderrPath ?? join5(homedir4(), "Library", "Logs", "opendevbrowser-daemon.err.log");
|
|
2020
|
-
const
|
|
2313
|
+
const workingDirectory = options.workingDirectory ?? resolveMacWorkingDirectory(homedir4());
|
|
2314
|
+
const programArgs = [entrypoint.nodePath, ...entrypoint.args].map((value) => ` <string>${escapePlistString(value)}</string>`).join("\n");
|
|
2021
2315
|
return [
|
|
2022
2316
|
'<?xml version="1.0" encoding="UTF-8"?>',
|
|
2023
2317
|
'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">',
|
|
2024
2318
|
'<plist version="1.0">',
|
|
2025
2319
|
"<dict>",
|
|
2026
2320
|
` <key>Label</key>`,
|
|
2027
|
-
` <string>${label}</string>`,
|
|
2321
|
+
` <string>${escapePlistString(label)}</string>`,
|
|
2028
2322
|
" <key>ProgramArguments</key>",
|
|
2029
2323
|
" <array>",
|
|
2030
2324
|
programArgs,
|
|
@@ -2033,10 +2327,12 @@ var buildLaunchAgentPlist = (entrypoint, options = {}) => {
|
|
|
2033
2327
|
" <true/>",
|
|
2034
2328
|
" <key>KeepAlive</key>",
|
|
2035
2329
|
" <true/>",
|
|
2330
|
+
" <key>WorkingDirectory</key>",
|
|
2331
|
+
` <string>${escapePlistString(workingDirectory)}</string>`,
|
|
2036
2332
|
" <key>StandardOutPath</key>",
|
|
2037
|
-
` <string>${stdoutPath}</string>`,
|
|
2333
|
+
` <string>${escapePlistString(stdoutPath)}</string>`,
|
|
2038
2334
|
" <key>StandardErrorPath</key>",
|
|
2039
|
-
` <string>${stderrPath}</string>`,
|
|
2335
|
+
` <string>${escapePlistString(stderrPath)}</string>`,
|
|
2040
2336
|
"</dict>",
|
|
2041
2337
|
"</plist>",
|
|
2042
2338
|
""
|
|
@@ -2128,6 +2424,7 @@ var readMacLaunchAgentProgramArguments = (plistPath, deps) => {
|
|
|
2128
2424
|
const text = deps.execFileSync("plutil", ["-convert", "json", "-o", "-", plistPath], { encoding: "utf-8" });
|
|
2129
2425
|
const parsed = JSON.parse(text);
|
|
2130
2426
|
const programArguments = parsed?.ProgramArguments;
|
|
2427
|
+
const workingDirectory = typeof parsed?.WorkingDirectory === "string" ? parsed.WorkingDirectory : void 0;
|
|
2131
2428
|
if (!Array.isArray(programArguments) || programArguments.length < 2 || programArguments.some((value) => typeof value !== "string")) {
|
|
2132
2429
|
return { ok: false, reason: "missing_program_arguments" };
|
|
2133
2430
|
}
|
|
@@ -2135,7 +2432,8 @@ var readMacLaunchAgentProgramArguments = (plistPath, deps) => {
|
|
|
2135
2432
|
return {
|
|
2136
2433
|
ok: true,
|
|
2137
2434
|
command: formatCommand(commandArgs),
|
|
2138
|
-
programArguments: commandArgs
|
|
2435
|
+
programArguments: commandArgs,
|
|
2436
|
+
...workingDirectory ? { workingDirectory } : {}
|
|
2139
2437
|
};
|
|
2140
2438
|
} catch {
|
|
2141
2439
|
return { ok: false, reason: "malformed_plist" };
|
|
@@ -2151,11 +2449,13 @@ var classifyMacAutostartStatus = (entrypoint, location, deps) => {
|
|
|
2151
2449
|
});
|
|
2152
2450
|
}
|
|
2153
2451
|
const parsed = readMacLaunchAgentProgramArguments(location, deps);
|
|
2452
|
+
const expectedWorkingDirectory = resolveMacWorkingDirectory(deps.homedir());
|
|
2154
2453
|
if (!parsed.ok) {
|
|
2155
2454
|
return createMacAutostartStatus(entrypoint, location, {
|
|
2156
2455
|
installed: true,
|
|
2157
2456
|
health: "malformed",
|
|
2158
2457
|
needsRepair: true,
|
|
2458
|
+
expectedWorkingDirectory,
|
|
2159
2459
|
reason: parsed.reason
|
|
2160
2460
|
});
|
|
2161
2461
|
}
|
|
@@ -2170,15 +2470,41 @@ var classifyMacAutostartStatus = (entrypoint, location, deps) => {
|
|
|
2170
2470
|
health: "needs_repair",
|
|
2171
2471
|
needsRepair: true,
|
|
2172
2472
|
command: parsed.command,
|
|
2473
|
+
workingDirectory: parsed.workingDirectory,
|
|
2474
|
+
expectedWorkingDirectory,
|
|
2173
2475
|
reason: actualStatus.reason
|
|
2174
2476
|
});
|
|
2175
2477
|
}
|
|
2478
|
+
if (parsed.workingDirectory !== expectedWorkingDirectory) {
|
|
2479
|
+
return createMacAutostartStatus(entrypoint, location, {
|
|
2480
|
+
installed: true,
|
|
2481
|
+
health: "needs_repair",
|
|
2482
|
+
needsRepair: true,
|
|
2483
|
+
command: parsed.command,
|
|
2484
|
+
workingDirectory: parsed.workingDirectory,
|
|
2485
|
+
expectedWorkingDirectory,
|
|
2486
|
+
reason: "working_directory_mismatch"
|
|
2487
|
+
});
|
|
2488
|
+
}
|
|
2489
|
+
if (!pathIsDirectory(expectedWorkingDirectory, deps)) {
|
|
2490
|
+
return createMacAutostartStatus(entrypoint, location, {
|
|
2491
|
+
installed: true,
|
|
2492
|
+
health: "needs_repair",
|
|
2493
|
+
needsRepair: true,
|
|
2494
|
+
command: parsed.command,
|
|
2495
|
+
workingDirectory: parsed.workingDirectory,
|
|
2496
|
+
expectedWorkingDirectory,
|
|
2497
|
+
reason: "working_directory_mismatch"
|
|
2498
|
+
});
|
|
2499
|
+
}
|
|
2176
2500
|
if (entrypoint.isTransient) {
|
|
2177
2501
|
return createMacAutostartStatus(entrypoint, location, {
|
|
2178
2502
|
installed: true,
|
|
2179
2503
|
health: "healthy",
|
|
2180
2504
|
needsRepair: false,
|
|
2181
|
-
command: parsed.command
|
|
2505
|
+
command: parsed.command,
|
|
2506
|
+
workingDirectory: parsed.workingDirectory,
|
|
2507
|
+
expectedWorkingDirectory
|
|
2182
2508
|
});
|
|
2183
2509
|
}
|
|
2184
2510
|
const mismatchReason = classifyExpectedProgramArguments(expectedArgs, actualArgs, deps);
|
|
@@ -2188,6 +2514,8 @@ var classifyMacAutostartStatus = (entrypoint, location, deps) => {
|
|
|
2188
2514
|
health: "needs_repair",
|
|
2189
2515
|
needsRepair: true,
|
|
2190
2516
|
command: parsed.command,
|
|
2517
|
+
workingDirectory: parsed.workingDirectory,
|
|
2518
|
+
expectedWorkingDirectory,
|
|
2191
2519
|
reason: mismatchReason
|
|
2192
2520
|
});
|
|
2193
2521
|
}
|
|
@@ -2195,7 +2523,9 @@ var classifyMacAutostartStatus = (entrypoint, location, deps) => {
|
|
|
2195
2523
|
installed: true,
|
|
2196
2524
|
health: "healthy",
|
|
2197
2525
|
needsRepair: false,
|
|
2198
|
-
command: parsed.command
|
|
2526
|
+
command: parsed.command,
|
|
2527
|
+
workingDirectory: parsed.workingDirectory,
|
|
2528
|
+
expectedWorkingDirectory
|
|
2199
2529
|
});
|
|
2200
2530
|
};
|
|
2201
2531
|
var runCommand = (exec, command, args, ignoreFailure = false) => {
|
|
@@ -2223,12 +2553,14 @@ var installMacAutostart = (deps = {}) => {
|
|
|
2223
2553
|
const plistPath = getLaunchAgentPath(home);
|
|
2224
2554
|
const stdoutPath = join5(home, "Library", "Logs", "opendevbrowser-daemon.log");
|
|
2225
2555
|
const stderrPath = join5(home, "Library", "Logs", "opendevbrowser-daemon.err.log");
|
|
2556
|
+
const workingDirectory = resolveMacWorkingDirectory(home);
|
|
2226
2557
|
const logsDir = dirname3(stdoutPath);
|
|
2227
2558
|
resolved.mkdirSync(dirname3(plistPath), { recursive: true });
|
|
2228
2559
|
resolved.mkdirSync(logsDir, { recursive: true });
|
|
2560
|
+
resolved.mkdirSync(workingDirectory, { recursive: true });
|
|
2229
2561
|
resolved.writeFileSync(
|
|
2230
2562
|
plistPath,
|
|
2231
|
-
buildLaunchAgentPlist(entrypoint, { stdoutPath, stderrPath }),
|
|
2563
|
+
buildLaunchAgentPlist(entrypoint, { stdoutPath, stderrPath, workingDirectory }),
|
|
2232
2564
|
{ encoding: "utf-8" }
|
|
2233
2565
|
);
|
|
2234
2566
|
const uid = resolved.uid;
|
|
@@ -2240,7 +2572,9 @@ var installMacAutostart = (deps = {}) => {
|
|
|
2240
2572
|
installed: true,
|
|
2241
2573
|
health: "healthy",
|
|
2242
2574
|
needsRepair: false,
|
|
2243
|
-
command: entrypoint.command
|
|
2575
|
+
command: entrypoint.command,
|
|
2576
|
+
workingDirectory,
|
|
2577
|
+
expectedWorkingDirectory: workingDirectory
|
|
2244
2578
|
});
|
|
2245
2579
|
};
|
|
2246
2580
|
var uninstallMacAutostart = (deps = {}) => {
|
|
@@ -2832,7 +3166,7 @@ function formatAutostartReconciliationMessage(result) {
|
|
|
2832
3166
|
}
|
|
2833
3167
|
|
|
2834
3168
|
// src/cli/commands/run.ts
|
|
2835
|
-
import { readFileSync as
|
|
3169
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
2836
3170
|
|
|
2837
3171
|
// src/cli/output.ts
|
|
2838
3172
|
var normalizeExitCode = (code) => {
|
|
@@ -2996,7 +3330,7 @@ async function runScriptCommand(args) {
|
|
|
2996
3330
|
const outputOptions = { format: args.outputFormat, quiet: args.quiet };
|
|
2997
3331
|
let scriptRaw = "";
|
|
2998
3332
|
if (runArgs.scriptPath) {
|
|
2999
|
-
scriptRaw =
|
|
3333
|
+
scriptRaw = readFileSync3(runArgs.scriptPath, "utf-8");
|
|
3000
3334
|
} else if (!process.stdin.isTTY) {
|
|
3001
3335
|
scriptRaw = await readScriptFromStdin();
|
|
3002
3336
|
} else {
|
|
@@ -3356,6 +3690,11 @@ var readRunnableStepCommand = (step) => {
|
|
|
3356
3690
|
if (!command) return null;
|
|
3357
3691
|
return UNRESOLVED_COMMAND_PLACEHOLDER_RE.test(command) ? null : command;
|
|
3358
3692
|
};
|
|
3693
|
+
var readDisplayableNextStep = (value) => {
|
|
3694
|
+
const text = readNonEmptyString(value);
|
|
3695
|
+
if (!text) return null;
|
|
3696
|
+
return UNRESOLVED_COMMAND_PLACEHOLDER_RE.test(text) ? null : text;
|
|
3697
|
+
};
|
|
3359
3698
|
var readMeta = (data) => {
|
|
3360
3699
|
return asRecord(asRecord(data)?.meta);
|
|
3361
3700
|
};
|
|
@@ -3378,6 +3717,9 @@ var readPrimaryNextStep = (data) => {
|
|
|
3378
3717
|
const nextStep = commands.find((entry) => typeof entry === "string" && entry.trim().length > 0);
|
|
3379
3718
|
return nextStep?.trim() ?? null;
|
|
3380
3719
|
};
|
|
3720
|
+
var inferPrimaryIssueNextStep = (data) => {
|
|
3721
|
+
return summarizePrimaryProviderIssue(readFailures(data))?.guidance?.recommendedNextCommands[0] ?? null;
|
|
3722
|
+
};
|
|
3381
3723
|
var readFailures = (data) => {
|
|
3382
3724
|
const meta = readMeta(data);
|
|
3383
3725
|
if (!meta) return [];
|
|
@@ -3396,12 +3738,27 @@ var readSuggestedSteps = (data) => {
|
|
|
3396
3738
|
}) : [];
|
|
3397
3739
|
};
|
|
3398
3740
|
var buildNextStepMessage = (message, nextStep) => {
|
|
3399
|
-
|
|
3741
|
+
const displayableNextStep = readDisplayableNextStep(nextStep);
|
|
3742
|
+
return displayableNextStep ? `${message} Next step: ${displayableNextStep}` : message;
|
|
3743
|
+
};
|
|
3744
|
+
var buildProviderFollowupErrorMessage = (message) => {
|
|
3745
|
+
const normalized = message.toLowerCase();
|
|
3746
|
+
if (normalized.includes("next step:")) return message;
|
|
3747
|
+
if (normalized.includes("requires login or an existing session")) {
|
|
3748
|
+
return buildNextStepMessage(
|
|
3749
|
+
message,
|
|
3750
|
+
"Reuse an authenticated browser session, import logged-in cookies, or use the provider sign-in flow."
|
|
3751
|
+
);
|
|
3752
|
+
}
|
|
3753
|
+
if (normalized.includes("requires manual browser follow-up") || normalized.includes("requires a live browser-rendered page")) {
|
|
3754
|
+
return buildNextStepMessage(message, "Retry with browser assistance or a headed browser session.");
|
|
3755
|
+
}
|
|
3756
|
+
return message;
|
|
3400
3757
|
};
|
|
3401
3758
|
var readSuggestedNextAction = (data) => {
|
|
3402
3759
|
const record = asRecord(data);
|
|
3403
3760
|
if (!record) return null;
|
|
3404
|
-
return
|
|
3761
|
+
return readDisplayableNextStep(record.suggestedNextAction) ?? readDisplayableNextStep(asRecord(record.sessionInspector)?.suggestedNextAction);
|
|
3405
3762
|
};
|
|
3406
3763
|
var readSuggestedStepCommand = (data) => {
|
|
3407
3764
|
let current = asRecord(data);
|
|
@@ -3419,18 +3776,19 @@ var readSuggestedStepReason = (data) => {
|
|
|
3419
3776
|
while (current) {
|
|
3420
3777
|
const [firstStep] = readSuggestedSteps(current);
|
|
3421
3778
|
if (firstStep) {
|
|
3422
|
-
return
|
|
3779
|
+
return readDisplayableNextStep(firstStep.reason);
|
|
3423
3780
|
}
|
|
3424
3781
|
current = asRecord(current.challengePlan);
|
|
3425
3782
|
}
|
|
3426
3783
|
return null;
|
|
3427
3784
|
};
|
|
3785
|
+
var readWorkflowGuidanceNextStep = (data) => readSuggestedNextAction(data) ?? readSuggestedStepCommand(data) ?? readSuggestedStepReason(data);
|
|
3428
3786
|
var buildWorkflowCompletionMessage = (workflowLabel, data) => {
|
|
3429
3787
|
const explicitSummary = readPrimarySummary(data);
|
|
3430
3788
|
if (explicitSummary) {
|
|
3431
3789
|
return buildNextStepMessage(
|
|
3432
3790
|
`${workflowLabel} completed with provider follow-up required: ${explicitSummary}`,
|
|
3433
|
-
readPrimaryNextStep(data)
|
|
3791
|
+
readPrimaryNextStep(data) ?? inferPrimaryIssueNextStep(data)
|
|
3434
3792
|
);
|
|
3435
3793
|
}
|
|
3436
3794
|
const inferred = summarizePrimaryProviderIssue(readFailures(data));
|
|
@@ -3444,7 +3802,7 @@ var buildWorkflowCompletionMessage = (workflowLabel, data) => {
|
|
|
3444
3802
|
if (followthroughSummary) {
|
|
3445
3803
|
return buildNextStepMessage(
|
|
3446
3804
|
`${workflowLabel} completed. ${followthroughSummary}`,
|
|
3447
|
-
|
|
3805
|
+
readWorkflowGuidanceNextStep(data)
|
|
3448
3806
|
);
|
|
3449
3807
|
}
|
|
3450
3808
|
return `${workflowLabel} completed.`;
|
|
@@ -3929,12 +4287,12 @@ function parseSnapshotArgs(rawArgs) {
|
|
|
3929
4287
|
if (arg === "--max-chars") {
|
|
3930
4288
|
const value = rawArgs[i + 1];
|
|
3931
4289
|
if (!value) throw createUsageError("Missing value for --max-chars");
|
|
3932
|
-
parsed.maxChars =
|
|
4290
|
+
parsed.maxChars = parseNumberFlag(value, "--max-chars", { min: 1 });
|
|
3933
4291
|
i += 1;
|
|
3934
4292
|
continue;
|
|
3935
4293
|
}
|
|
3936
4294
|
if (arg?.startsWith("--max-chars=")) {
|
|
3937
|
-
parsed.maxChars =
|
|
4295
|
+
parsed.maxChars = parseNumberFlag(arg.split("=", 2)[1] ?? "", "--max-chars", { min: 1 });
|
|
3938
4296
|
continue;
|
|
3939
4297
|
}
|
|
3940
4298
|
if (arg === "--cursor") {
|
|
@@ -4193,7 +4551,7 @@ async function runAnnotate(args) {
|
|
|
4193
4551
|
}
|
|
4194
4552
|
|
|
4195
4553
|
// src/cli/commands/canvas.ts
|
|
4196
|
-
import { readFileSync as
|
|
4554
|
+
import { readFileSync as readFileSync4 } from "fs";
|
|
4197
4555
|
var DEFAULT_FEEDBACK_STREAM_TIMEOUT_MS = 3e4;
|
|
4198
4556
|
var isRecord = (value) => {
|
|
4199
4557
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -4394,7 +4752,7 @@ var resolveCanvasParams = (canvasArgs) => {
|
|
|
4394
4752
|
if (hasParamsFile) {
|
|
4395
4753
|
let raw = "";
|
|
4396
4754
|
try {
|
|
4397
|
-
raw =
|
|
4755
|
+
raw = readFileSync4(canvasArgs.paramsFile ?? "", "utf8");
|
|
4398
4756
|
} catch (error) {
|
|
4399
4757
|
const message = error instanceof Error ? error.message : "Unable to read file";
|
|
4400
4758
|
throw createUsageError(`Invalid --params-file: ${message}`);
|
|
@@ -4463,7 +4821,7 @@ async function runCanvas(args) {
|
|
|
4463
4821
|
}
|
|
4464
4822
|
|
|
4465
4823
|
// src/cli/commands/rpc.ts
|
|
4466
|
-
import { readFileSync as
|
|
4824
|
+
import { readFileSync as readFileSync5 } from "fs";
|
|
4467
4825
|
var requireValue4 = (value, flag) => {
|
|
4468
4826
|
if (!value) throw createUsageError(`Missing value for ${flag}`);
|
|
4469
4827
|
return value;
|
|
@@ -4543,7 +4901,7 @@ var resolveRpcParams = (rpcArgs) => {
|
|
|
4543
4901
|
if (hasParamsFile) {
|
|
4544
4902
|
let raw = "";
|
|
4545
4903
|
try {
|
|
4546
|
-
raw =
|
|
4904
|
+
raw = readFileSync5(rpcArgs.paramsFile ?? "", "utf8");
|
|
4547
4905
|
} catch (error) {
|
|
4548
4906
|
const message = error instanceof Error ? error.message : "Unable to read file";
|
|
4549
4907
|
throw createUsageError(`Invalid --params-file: ${message}`);
|
|
@@ -4974,12 +5332,12 @@ function parseScrollArgs(rawArgs) {
|
|
|
4974
5332
|
if (arg === "--dy") {
|
|
4975
5333
|
const value = rawArgs[i + 1];
|
|
4976
5334
|
if (!value) throw createUsageError("Missing value for --dy");
|
|
4977
|
-
parsed.dy =
|
|
5335
|
+
parsed.dy = parseNumberFlag(value, "--dy");
|
|
4978
5336
|
i += 1;
|
|
4979
5337
|
continue;
|
|
4980
5338
|
}
|
|
4981
5339
|
if (arg?.startsWith("--dy=")) {
|
|
4982
|
-
parsed.dy =
|
|
5340
|
+
parsed.dy = parseNumberFlag(arg.split("=", 2)[1] ?? "", "--dy");
|
|
4983
5341
|
continue;
|
|
4984
5342
|
}
|
|
4985
5343
|
}
|
|
@@ -5475,12 +5833,12 @@ function parseDomHtmlArgs(rawArgs) {
|
|
|
5475
5833
|
if (arg === "--max-chars") {
|
|
5476
5834
|
const value = rawArgs[i + 1];
|
|
5477
5835
|
if (!value) throw createUsageError("Missing value for --max-chars");
|
|
5478
|
-
parsed.maxChars =
|
|
5836
|
+
parsed.maxChars = parseNumberFlag(value, "--max-chars", { min: 1 });
|
|
5479
5837
|
i += 1;
|
|
5480
5838
|
continue;
|
|
5481
5839
|
}
|
|
5482
5840
|
if (arg?.startsWith("--max-chars=")) {
|
|
5483
|
-
parsed.maxChars =
|
|
5841
|
+
parsed.maxChars = parseNumberFlag(arg.split("=", 2)[1] ?? "", "--max-chars", { min: 1 });
|
|
5484
5842
|
continue;
|
|
5485
5843
|
}
|
|
5486
5844
|
}
|
|
@@ -5530,12 +5888,12 @@ function parseDomTextArgs(rawArgs) {
|
|
|
5530
5888
|
if (arg === "--max-chars") {
|
|
5531
5889
|
const value = rawArgs[i + 1];
|
|
5532
5890
|
if (!value) throw createUsageError("Missing value for --max-chars");
|
|
5533
|
-
parsed.maxChars =
|
|
5891
|
+
parsed.maxChars = parseNumberFlag(value, "--max-chars", { min: 1 });
|
|
5534
5892
|
i += 1;
|
|
5535
5893
|
continue;
|
|
5536
5894
|
}
|
|
5537
5895
|
if (arg?.startsWith("--max-chars=")) {
|
|
5538
|
-
parsed.maxChars =
|
|
5896
|
+
parsed.maxChars = parseNumberFlag(arg.split("=", 2)[1] ?? "", "--max-chars", { min: 1 });
|
|
5539
5897
|
continue;
|
|
5540
5898
|
}
|
|
5541
5899
|
}
|
|
@@ -6050,23 +6408,23 @@ function parseConsolePollArgs(rawArgs) {
|
|
|
6050
6408
|
if (arg === "--since-seq") {
|
|
6051
6409
|
const value = rawArgs[i + 1];
|
|
6052
6410
|
if (!value) throw createUsageError("Missing value for --since-seq");
|
|
6053
|
-
parsed.sinceSeq =
|
|
6411
|
+
parsed.sinceSeq = parseNumberFlag(value, "--since-seq", { min: 0 });
|
|
6054
6412
|
i += 1;
|
|
6055
6413
|
continue;
|
|
6056
6414
|
}
|
|
6057
6415
|
if (arg?.startsWith("--since-seq=")) {
|
|
6058
|
-
parsed.sinceSeq =
|
|
6416
|
+
parsed.sinceSeq = parseNumberFlag(arg.split("=", 2)[1] ?? "", "--since-seq", { min: 0 });
|
|
6059
6417
|
continue;
|
|
6060
6418
|
}
|
|
6061
6419
|
if (arg === "--max") {
|
|
6062
6420
|
const value = rawArgs[i + 1];
|
|
6063
6421
|
if (!value) throw createUsageError("Missing value for --max");
|
|
6064
|
-
parsed.max =
|
|
6422
|
+
parsed.max = parseNumberFlag(value, "--max", { min: 1 });
|
|
6065
6423
|
i += 1;
|
|
6066
6424
|
continue;
|
|
6067
6425
|
}
|
|
6068
6426
|
if (arg?.startsWith("--max=")) {
|
|
6069
|
-
parsed.max =
|
|
6427
|
+
parsed.max = parseNumberFlag(arg.split("=", 2)[1] ?? "", "--max", { min: 1 });
|
|
6070
6428
|
continue;
|
|
6071
6429
|
}
|
|
6072
6430
|
}
|
|
@@ -6098,23 +6456,23 @@ function parseNetworkPollArgs(rawArgs) {
|
|
|
6098
6456
|
if (arg === "--since-seq") {
|
|
6099
6457
|
const value = rawArgs[i + 1];
|
|
6100
6458
|
if (!value) throw createUsageError("Missing value for --since-seq");
|
|
6101
|
-
parsed.sinceSeq =
|
|
6459
|
+
parsed.sinceSeq = parseNumberFlag(value, "--since-seq", { min: 0 });
|
|
6102
6460
|
i += 1;
|
|
6103
6461
|
continue;
|
|
6104
6462
|
}
|
|
6105
6463
|
if (arg?.startsWith("--since-seq=")) {
|
|
6106
|
-
parsed.sinceSeq =
|
|
6464
|
+
parsed.sinceSeq = parseNumberFlag(arg.split("=", 2)[1] ?? "", "--since-seq", { min: 0 });
|
|
6107
6465
|
continue;
|
|
6108
6466
|
}
|
|
6109
6467
|
if (arg === "--max") {
|
|
6110
6468
|
const value = rawArgs[i + 1];
|
|
6111
6469
|
if (!value) throw createUsageError("Missing value for --max");
|
|
6112
|
-
parsed.max =
|
|
6470
|
+
parsed.max = parseNumberFlag(value, "--max", { min: 1 });
|
|
6113
6471
|
i += 1;
|
|
6114
6472
|
continue;
|
|
6115
6473
|
}
|
|
6116
6474
|
if (arg?.startsWith("--max=")) {
|
|
6117
|
-
parsed.max =
|
|
6475
|
+
parsed.max = parseNumberFlag(arg.split("=", 2)[1] ?? "", "--max", { min: 1 });
|
|
6118
6476
|
continue;
|
|
6119
6477
|
}
|
|
6120
6478
|
}
|
|
@@ -6326,7 +6684,7 @@ async function runDesktopAccessibilitySnapshot(args) {
|
|
|
6326
6684
|
}
|
|
6327
6685
|
|
|
6328
6686
|
// src/cli/commands/session/cookie-import.ts
|
|
6329
|
-
import { readFileSync as
|
|
6687
|
+
import { readFileSync as readFileSync6 } from "fs";
|
|
6330
6688
|
var requireValue5 = (value, flag) => {
|
|
6331
6689
|
if (!value) {
|
|
6332
6690
|
throw createUsageError(`Missing value for ${flag}`);
|
|
@@ -6441,7 +6799,7 @@ var resolveCookies = (parsed) => {
|
|
|
6441
6799
|
}
|
|
6442
6800
|
let raw = "";
|
|
6443
6801
|
try {
|
|
6444
|
-
raw =
|
|
6802
|
+
raw = readFileSync6(parsed.cookiesFile ?? "", "utf8");
|
|
6445
6803
|
} catch (error) {
|
|
6446
6804
|
const message = error instanceof Error ? error.message : "Unable to read file";
|
|
6447
6805
|
throw createUsageError(`Invalid --cookies-file: ${message}`);
|
|
@@ -6560,6 +6918,7 @@ async function runCookieList(args) {
|
|
|
6560
6918
|
|
|
6561
6919
|
// src/cli/commands/macro-resolve.ts
|
|
6562
6920
|
var MACRO_TRANSPORT_TIMEOUT_BUFFER_MS = 6e4;
|
|
6921
|
+
var BROWSER_MODE_VALUES = /* @__PURE__ */ new Set(["auto", "extension", "managed"]);
|
|
6563
6922
|
var deriveMacroTransportTimeoutMs = (timeoutMs) => {
|
|
6564
6923
|
return Math.max(
|
|
6565
6924
|
DEFAULT_WORKFLOW_TRANSPORT_TIMEOUT_MS,
|
|
@@ -6578,27 +6937,16 @@ var asRecord2 = (value) => {
|
|
|
6578
6937
|
}
|
|
6579
6938
|
return value;
|
|
6580
6939
|
};
|
|
6581
|
-
var readNonEmptyString2 = (value) => typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
6582
6940
|
var hasExecutionBlocker = (result) => {
|
|
6583
6941
|
const execution = asRecord2(asRecord2(result)?.execution);
|
|
6584
6942
|
const meta = asRecord2(execution?.meta);
|
|
6585
6943
|
return asRecord2(meta?.blocker) !== null;
|
|
6586
6944
|
};
|
|
6587
|
-
var readMacroResolveSummary = (result) => readNonEmptyString2(asRecord2(result)?.followthroughSummary);
|
|
6588
|
-
var readMacroResolveNextStep = (result) => {
|
|
6589
|
-
const record = asRecord2(result);
|
|
6590
|
-
const explicit = readNonEmptyString2(record?.suggestedNextAction);
|
|
6591
|
-
if (explicit) {
|
|
6592
|
-
return explicit;
|
|
6593
|
-
}
|
|
6594
|
-
const [firstStep] = Array.isArray(record?.suggestedSteps) ? record.suggestedSteps.filter((step) => Boolean(step) && typeof step === "object") : [];
|
|
6595
|
-
return readNonEmptyString2(firstStep?.command) ?? readNonEmptyString2(firstStep?.reason);
|
|
6596
|
-
};
|
|
6597
6945
|
var buildMacroResolveMessage = (execute, result) => {
|
|
6598
|
-
const summary =
|
|
6599
|
-
const nextStep =
|
|
6946
|
+
const summary = readFollowthroughSummary(result);
|
|
6947
|
+
const nextStep = readWorkflowGuidanceNextStep(result);
|
|
6600
6948
|
if (summary) {
|
|
6601
|
-
return
|
|
6949
|
+
return buildNextStepMessage(summary, nextStep);
|
|
6602
6950
|
}
|
|
6603
6951
|
if (!execute) {
|
|
6604
6952
|
return "Macro resolved.";
|
|
@@ -6648,6 +6996,23 @@ var parseMacroResolveArgs = (rawArgs) => {
|
|
|
6648
6996
|
parsed.timeoutMs = parseNumberFlag(requireValue7(arg.split("=", 2)[1], "--timeout-ms"), "--timeout-ms", { min: 1 });
|
|
6649
6997
|
continue;
|
|
6650
6998
|
}
|
|
6999
|
+
if (arg === "--browser-mode") {
|
|
7000
|
+
const value = requireValue7(rawArgs[index + 1], "--browser-mode").toLowerCase();
|
|
7001
|
+
if (!BROWSER_MODE_VALUES.has(value)) {
|
|
7002
|
+
throw createUsageError(`Invalid --browser-mode: ${value}`);
|
|
7003
|
+
}
|
|
7004
|
+
parsed.browserMode = value;
|
|
7005
|
+
index += 1;
|
|
7006
|
+
continue;
|
|
7007
|
+
}
|
|
7008
|
+
if (arg?.startsWith("--browser-mode=")) {
|
|
7009
|
+
const value = requireValue7(arg.split("=", 2)[1], "--browser-mode").toLowerCase();
|
|
7010
|
+
if (!BROWSER_MODE_VALUES.has(value)) {
|
|
7011
|
+
throw createUsageError(`Invalid --browser-mode: ${value}`);
|
|
7012
|
+
}
|
|
7013
|
+
parsed.browserMode = value;
|
|
7014
|
+
continue;
|
|
7015
|
+
}
|
|
6651
7016
|
if (arg === "--challenge-automation-mode") {
|
|
6652
7017
|
const value = requireValue7(rawArgs[index + 1], "--challenge-automation-mode");
|
|
6653
7018
|
if (!isChallengeAutomationMode(value)) {
|
|
@@ -6673,12 +7038,19 @@ async function runMacroResolve(args) {
|
|
|
6673
7038
|
if (!parsed.expression) {
|
|
6674
7039
|
throw createUsageError("Missing --expression");
|
|
6675
7040
|
}
|
|
7041
|
+
if (!parsed.execute && parsed.browserMode) {
|
|
7042
|
+
throw createUsageError("--browser-mode requires --execute for macro-resolve");
|
|
7043
|
+
}
|
|
7044
|
+
if (!parsed.execute && parsed.challengeAutomationMode) {
|
|
7045
|
+
throw createUsageError("--challenge-automation-mode requires --execute for macro-resolve");
|
|
7046
|
+
}
|
|
6676
7047
|
const params = {
|
|
6677
7048
|
expression: parsed.expression,
|
|
6678
7049
|
defaultProvider: parsed.defaultProvider,
|
|
6679
7050
|
includeCatalog: parsed.includeCatalog ?? false,
|
|
6680
7051
|
execute: parsed.execute ?? false,
|
|
6681
7052
|
...typeof parsed.timeoutMs === "number" ? { timeoutMs: parsed.timeoutMs } : {},
|
|
7053
|
+
...parsed.browserMode ? { browserMode: parsed.browserMode } : {},
|
|
6682
7054
|
...parsed.challengeAutomationMode ? { challengeAutomationMode: parsed.challengeAutomationMode } : {}
|
|
6683
7055
|
};
|
|
6684
7056
|
const result = typeof parsed.timeoutMs === "number" ? await callDaemon("macro.resolve", params, {
|
|
@@ -6695,6 +7067,7 @@ async function runMacroResolve(args) {
|
|
|
6695
7067
|
var SOURCE_VALUES = /* @__PURE__ */ new Set(["web", "community", "social", "shopping"]);
|
|
6696
7068
|
var SOURCE_SELECTION_VALUES = /* @__PURE__ */ new Set(["auto", "web", "community", "social", "shopping", "all"]);
|
|
6697
7069
|
var MODE_VALUES = /* @__PURE__ */ new Set(["compact", "json", "md", "context", "path"]);
|
|
7070
|
+
var BROWSER_MODE_VALUES2 = /* @__PURE__ */ new Set(["auto", "extension", "managed"]);
|
|
6698
7071
|
var COOKIE_POLICY_VALUES = /* @__PURE__ */ new Set(["off", "auto", "required"]);
|
|
6699
7072
|
var requireValue8 = (rawArgs, index, flag) => {
|
|
6700
7073
|
const value = rawArgs[index + 1];
|
|
@@ -6844,6 +7217,23 @@ var parseResearchRunArgs = (rawArgs) => {
|
|
|
6844
7217
|
parsed.ttlHours = parseNumberFlag(arg.split("=", 2)[1] ?? "", "--ttl-hours", { min: 1, max: 168 });
|
|
6845
7218
|
continue;
|
|
6846
7219
|
}
|
|
7220
|
+
if (arg === "--browser-mode") {
|
|
7221
|
+
const value = requireValue8(rawArgs, index, "--browser-mode").toLowerCase();
|
|
7222
|
+
if (!BROWSER_MODE_VALUES2.has(value)) {
|
|
7223
|
+
throw createUsageError(`Invalid --browser-mode: ${value}`);
|
|
7224
|
+
}
|
|
7225
|
+
parsed.browserMode = value;
|
|
7226
|
+
index += 1;
|
|
7227
|
+
continue;
|
|
7228
|
+
}
|
|
7229
|
+
if (arg?.startsWith("--browser-mode=")) {
|
|
7230
|
+
const value = (arg.split("=", 2)[1] ?? "").toLowerCase();
|
|
7231
|
+
if (!BROWSER_MODE_VALUES2.has(value)) {
|
|
7232
|
+
throw createUsageError(`Invalid --browser-mode: ${value}`);
|
|
7233
|
+
}
|
|
7234
|
+
parsed.browserMode = value;
|
|
7235
|
+
continue;
|
|
7236
|
+
}
|
|
6847
7237
|
if (arg === "--use-cookies") {
|
|
6848
7238
|
parsed.useCookies = true;
|
|
6849
7239
|
continue;
|
|
@@ -6911,6 +7301,7 @@ async function runResearchCommand(args) {
|
|
|
6911
7301
|
timeoutMs: parsed.timeoutMs ?? DEFAULT_WORKFLOW_TRANSPORT_TIMEOUT_MS,
|
|
6912
7302
|
outputDir: parsed.outputDir,
|
|
6913
7303
|
ttlHours: parsed.ttlHours,
|
|
7304
|
+
browserMode: parsed.browserMode,
|
|
6914
7305
|
useCookies: parsed.useCookies,
|
|
6915
7306
|
challengeAutomationMode: parsed.challengeAutomationMode,
|
|
6916
7307
|
cookiePolicyOverride: parsed.cookiePolicyOverride
|
|
@@ -6927,7 +7318,7 @@ async function runResearchCommand(args) {
|
|
|
6927
7318
|
var SORT_VALUES = /* @__PURE__ */ new Set(["best_deal", "lowest_price", "highest_rating", "fastest_shipping"]);
|
|
6928
7319
|
var MODE_VALUES2 = /* @__PURE__ */ new Set(["compact", "json", "md", "context", "path"]);
|
|
6929
7320
|
var COOKIE_POLICY_VALUES2 = /* @__PURE__ */ new Set(["off", "auto", "required"]);
|
|
6930
|
-
var
|
|
7321
|
+
var BROWSER_MODE_VALUES3 = /* @__PURE__ */ new Set(["auto", "extension", "managed"]);
|
|
6931
7322
|
var SHOPPING_TRANSPORT_TIMEOUT_BUFFER_MS = 6e4;
|
|
6932
7323
|
var deriveShoppingTransportTimeoutMs = (timeoutMs) => {
|
|
6933
7324
|
return Math.max(
|
|
@@ -6996,7 +7387,7 @@ var parseShoppingRunArgs = (rawArgs) => {
|
|
|
6996
7387
|
}
|
|
6997
7388
|
if (arg === "--browser-mode") {
|
|
6998
7389
|
const value = requireValue9(rawArgs, index, "--browser-mode").toLowerCase();
|
|
6999
|
-
if (!
|
|
7390
|
+
if (!BROWSER_MODE_VALUES3.has(value)) {
|
|
7000
7391
|
throw createUsageError(`Invalid --browser-mode: ${value}`);
|
|
7001
7392
|
}
|
|
7002
7393
|
parsed.browserMode = value;
|
|
@@ -7005,7 +7396,7 @@ var parseShoppingRunArgs = (rawArgs) => {
|
|
|
7005
7396
|
}
|
|
7006
7397
|
if (arg?.startsWith("--browser-mode=")) {
|
|
7007
7398
|
const value = (arg.split("=", 2)[1] ?? "").toLowerCase();
|
|
7008
|
-
if (!
|
|
7399
|
+
if (!BROWSER_MODE_VALUES3.has(value)) {
|
|
7009
7400
|
throw createUsageError(`Invalid --browser-mode: ${value}`);
|
|
7010
7401
|
}
|
|
7011
7402
|
parsed.browserMode = value;
|
|
@@ -7165,6 +7556,7 @@ var parseBoolean3 = (value, flag) => {
|
|
|
7165
7556
|
throw createUsageError(`Invalid ${flag}: ${value}`);
|
|
7166
7557
|
};
|
|
7167
7558
|
var COOKIE_POLICY_VALUES3 = /* @__PURE__ */ new Set(["off", "auto", "required"]);
|
|
7559
|
+
var BROWSER_MODE_VALUES4 = /* @__PURE__ */ new Set(["auto", "extension", "managed"]);
|
|
7168
7560
|
var parseProductVideoArgs = (rawArgs) => {
|
|
7169
7561
|
const parsed = {};
|
|
7170
7562
|
for (let index = 0; index < rawArgs.length; index += 1) {
|
|
@@ -7247,6 +7639,23 @@ var parseProductVideoArgs = (rawArgs) => {
|
|
|
7247
7639
|
parsed.timeoutMs = parseNumberFlag(arg.split("=", 2)[1] ?? "", "--timeout-ms", { min: 1 });
|
|
7248
7640
|
continue;
|
|
7249
7641
|
}
|
|
7642
|
+
if (arg === "--browser-mode") {
|
|
7643
|
+
const value = requireValue10(rawArgs, index, "--browser-mode").toLowerCase();
|
|
7644
|
+
if (!BROWSER_MODE_VALUES4.has(value)) {
|
|
7645
|
+
throw createUsageError(`Invalid --browser-mode: ${value}`);
|
|
7646
|
+
}
|
|
7647
|
+
parsed.browserMode = value;
|
|
7648
|
+
index += 1;
|
|
7649
|
+
continue;
|
|
7650
|
+
}
|
|
7651
|
+
if (arg?.startsWith("--browser-mode=")) {
|
|
7652
|
+
const value = (arg.split("=", 2)[1] ?? "").toLowerCase();
|
|
7653
|
+
if (!BROWSER_MODE_VALUES4.has(value)) {
|
|
7654
|
+
throw createUsageError(`Invalid --browser-mode: ${value}`);
|
|
7655
|
+
}
|
|
7656
|
+
parsed.browserMode = value;
|
|
7657
|
+
continue;
|
|
7658
|
+
}
|
|
7250
7659
|
if (arg === "--use-cookies") {
|
|
7251
7660
|
parsed.useCookies = true;
|
|
7252
7661
|
continue;
|
|
@@ -7312,6 +7721,7 @@ async function runProductVideoCommand(args) {
|
|
|
7312
7721
|
output_dir: parsed.outputDir,
|
|
7313
7722
|
ttl_hours: parsed.ttlHours,
|
|
7314
7723
|
timeoutMs,
|
|
7724
|
+
browserMode: parsed.browserMode,
|
|
7315
7725
|
useCookies: parsed.useCookies,
|
|
7316
7726
|
challengeAutomationMode: parsed.challengeAutomationMode,
|
|
7317
7727
|
cookiePolicyOverride: parsed.cookiePolicyOverride
|
|
@@ -7327,6 +7737,7 @@ async function runProductVideoCommand(args) {
|
|
|
7327
7737
|
var MODE_VALUES3 = /* @__PURE__ */ new Set(["compact", "json", "md", "context", "path"]);
|
|
7328
7738
|
var CAPTURE_MODE_VALUES = /* @__PURE__ */ new Set(["off", "deep"]);
|
|
7329
7739
|
var COOKIE_POLICY_VALUES4 = /* @__PURE__ */ new Set(["off", "auto", "required"]);
|
|
7740
|
+
var BROWSER_MODE_VALUES5 = /* @__PURE__ */ new Set(["auto", "extension", "managed"]);
|
|
7330
7741
|
var requireValue11 = (rawArgs, index, flag) => {
|
|
7331
7742
|
const value = rawArgs[index + 1];
|
|
7332
7743
|
if (!value) {
|
|
@@ -7417,6 +7828,23 @@ var parseInspiredesignRunArgs = (rawArgs) => {
|
|
|
7417
7828
|
parsed.ttlHours = parseNumberFlag(arg.split("=", 2)[1] ?? "", "--ttl-hours", { min: 1, max: 168 });
|
|
7418
7829
|
continue;
|
|
7419
7830
|
}
|
|
7831
|
+
if (arg === "--browser-mode") {
|
|
7832
|
+
const value = requireValue11(rawArgs, index, "--browser-mode").toLowerCase();
|
|
7833
|
+
if (!BROWSER_MODE_VALUES5.has(value)) {
|
|
7834
|
+
throw createUsageError(`Invalid --browser-mode: ${value}`);
|
|
7835
|
+
}
|
|
7836
|
+
parsed.browserMode = value;
|
|
7837
|
+
index += 1;
|
|
7838
|
+
continue;
|
|
7839
|
+
}
|
|
7840
|
+
if (arg?.startsWith("--browser-mode=")) {
|
|
7841
|
+
const value = (arg.split("=", 2)[1] ?? "").toLowerCase();
|
|
7842
|
+
if (!BROWSER_MODE_VALUES5.has(value)) {
|
|
7843
|
+
throw createUsageError(`Invalid --browser-mode: ${value}`);
|
|
7844
|
+
}
|
|
7845
|
+
parsed.browserMode = value;
|
|
7846
|
+
continue;
|
|
7847
|
+
}
|
|
7420
7848
|
if (arg === "--use-cookies") {
|
|
7421
7849
|
parsed.useCookies = true;
|
|
7422
7850
|
continue;
|
|
@@ -7480,6 +7908,7 @@ async function runInspiredesignCommand(args) {
|
|
|
7480
7908
|
timeoutMs: parsed.timeoutMs ?? DEFAULT_WORKFLOW_TRANSPORT_TIMEOUT_MS,
|
|
7481
7909
|
outputDir: parsed.outputDir,
|
|
7482
7910
|
ttlHours: parsed.ttlHours,
|
|
7911
|
+
browserMode: parsed.browserMode,
|
|
7483
7912
|
useCookies: parsed.useCookies,
|
|
7484
7913
|
challengeAutomationMode: parsed.challengeAutomationMode,
|
|
7485
7914
|
cookiePolicyOverride: parsed.cookiePolicyOverride
|
|
@@ -7494,7 +7923,7 @@ async function runInspiredesignCommand(args) {
|
|
|
7494
7923
|
// package.json
|
|
7495
7924
|
var package_default = {
|
|
7496
7925
|
name: "opendevbrowser",
|
|
7497
|
-
version: "0.0.
|
|
7926
|
+
version: "0.0.28",
|
|
7498
7927
|
description: "Browser automation runtime with snapshot-refs-actions, browser replay screencasts, public read-only desktop observation, and browser-scoped computer-use orchestration",
|
|
7499
7928
|
type: "module",
|
|
7500
7929
|
main: "dist/index.js",
|
|
@@ -7776,14 +8205,15 @@ async function promptUninstallMode() {
|
|
|
7776
8205
|
});
|
|
7777
8206
|
}
|
|
7778
8207
|
function emitFatalError(error, outputFormat) {
|
|
8208
|
+
const message = buildProviderFollowupErrorMessage(error.message);
|
|
7779
8209
|
if (outputFormat === "text") {
|
|
7780
|
-
console.error(`Error: ${
|
|
8210
|
+
console.error(`Error: ${message}`);
|
|
7781
8211
|
if (error.exitCode === EXIT_USAGE) {
|
|
7782
8212
|
console.error("\nFor help: npx opendevbrowser --help");
|
|
7783
8213
|
}
|
|
7784
8214
|
return;
|
|
7785
8215
|
}
|
|
7786
|
-
writeOutput(formatErrorPayload(error), { format: outputFormat });
|
|
8216
|
+
writeOutput({ ...formatErrorPayload(error), error: message }, { format: outputFormat });
|
|
7787
8217
|
}
|
|
7788
8218
|
async function main() {
|
|
7789
8219
|
let outputFormat = null;
|
|
@@ -7828,7 +8258,7 @@ async function main() {
|
|
|
7828
8258
|
});
|
|
7829
8259
|
registerCommand({
|
|
7830
8260
|
name: "update",
|
|
7831
|
-
description: "
|
|
8261
|
+
description: "Repair cached plugin pins and refresh managed skill packs",
|
|
7832
8262
|
run: () => buildUpdateCommandResult(args, runUpdate(), {
|
|
7833
8263
|
resolveUpdateSkillModes,
|
|
7834
8264
|
hasInstalledConfig,
|