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.
Files changed (102) hide show
  1. package/README.md +7 -10
  2. package/dist/browser/canvas-manager.d.ts.map +1 -1
  3. package/dist/canvas/document-store.d.ts.map +1 -1
  4. package/dist/canvas/guidance.d.ts +22 -0
  5. package/dist/canvas/guidance.d.ts.map +1 -0
  6. package/dist/canvas/types.d.ts +3 -0
  7. package/dist/canvas/types.d.ts.map +1 -1
  8. package/dist/{chunk-GTTYIAI7.js → chunk-I5ZCOZZV.js} +316 -94
  9. package/dist/chunk-I5ZCOZZV.js.map +1 -0
  10. package/dist/{chunk-AVQL6WAS.js → chunk-T3VVHJTK.js} +2384 -544
  11. package/dist/chunk-T3VVHJTK.js.map +1 -0
  12. package/dist/cli/args.d.ts.map +1 -1
  13. package/dist/cli/commands/daemon.d.ts +2 -0
  14. package/dist/cli/commands/daemon.d.ts.map +1 -1
  15. package/dist/cli/commands/devtools/console-poll.d.ts.map +1 -1
  16. package/dist/cli/commands/devtools/network-poll.d.ts.map +1 -1
  17. package/dist/cli/commands/inspiredesign.d.ts +2 -0
  18. package/dist/cli/commands/inspiredesign.d.ts.map +1 -1
  19. package/dist/cli/commands/macro-resolve.d.ts +2 -0
  20. package/dist/cli/commands/macro-resolve.d.ts.map +1 -1
  21. package/dist/cli/commands/product-video.d.ts +2 -0
  22. package/dist/cli/commands/product-video.d.ts.map +1 -1
  23. package/dist/cli/commands/research.d.ts +2 -0
  24. package/dist/cli/commands/research.d.ts.map +1 -1
  25. package/dist/cli/commands/update.d.ts.map +1 -1
  26. package/dist/cli/daemon-autostart.d.ts +6 -2
  27. package/dist/cli/daemon-autostart.d.ts.map +1 -1
  28. package/dist/cli/daemon-commands.d.ts.map +1 -1
  29. package/dist/cli/help.d.ts.map +1 -1
  30. package/dist/cli/index.js +516 -86
  31. package/dist/cli/index.js.map +1 -1
  32. package/dist/cli/utils/parse.d.ts.map +1 -1
  33. package/dist/cli/utils/workflow-message.d.ts +3 -0
  34. package/dist/cli/utils/workflow-message.d.ts.map +1 -1
  35. package/dist/daemon-fingerprint.json +1 -1
  36. package/dist/index.js +39 -15
  37. package/dist/index.js.map +1 -1
  38. package/dist/inspiredesign/brief-expansion.d.ts +3 -0
  39. package/dist/inspiredesign/brief-expansion.d.ts.map +1 -1
  40. package/dist/{providers/inspiredesign-capture-mode.d.ts → inspiredesign/capture-mode.d.ts} +2 -2
  41. package/dist/inspiredesign/capture-mode.d.ts.map +1 -0
  42. package/dist/{providers/inspiredesign-capture.d.ts → inspiredesign/capture.d.ts} +3 -3
  43. package/dist/inspiredesign/capture.d.ts.map +1 -0
  44. package/dist/{providers/inspiredesign-contract.d.ts → inspiredesign/contract.d.ts} +70 -6
  45. package/dist/inspiredesign/contract.d.ts.map +1 -0
  46. package/dist/inspiredesign/handoff.d.ts +12 -10
  47. package/dist/inspiredesign/handoff.d.ts.map +1 -1
  48. package/dist/inspiredesign/reference-pattern-board.d.ts +74 -0
  49. package/dist/inspiredesign/reference-pattern-board.d.ts.map +1 -0
  50. package/dist/macros/execute-runtime.d.ts +2 -1
  51. package/dist/macros/execute-runtime.d.ts.map +1 -1
  52. package/dist/macros/execute.d.ts +4 -2
  53. package/dist/macros/execute.d.ts.map +1 -1
  54. package/dist/opendevbrowser.js +39 -15
  55. package/dist/opendevbrowser.js.map +1 -1
  56. package/dist/providers/browser-fallback.d.ts +7 -0
  57. package/dist/providers/browser-fallback.d.ts.map +1 -1
  58. package/dist/providers/community/index.d.ts.map +1 -1
  59. package/dist/providers/index.d.ts.map +1 -1
  60. package/dist/providers/renderer.d.ts +1 -1
  61. package/dist/providers/renderer.d.ts.map +1 -1
  62. package/dist/providers/research-compiler.d.ts.map +1 -1
  63. package/dist/providers/runtime-bundle.d.ts +1 -1
  64. package/dist/providers/runtime-bundle.d.ts.map +1 -1
  65. package/dist/providers/runtime-factory.d.ts.map +1 -1
  66. package/dist/providers/shopping/index.d.ts.map +1 -1
  67. package/dist/providers/social/platform.d.ts.map +1 -1
  68. package/dist/providers/social/search-quality.d.ts.map +1 -1
  69. package/dist/providers/social/youtube.d.ts.map +1 -1
  70. package/dist/providers/workflow-handoff.d.ts +18 -1
  71. package/dist/providers/workflow-handoff.d.ts.map +1 -1
  72. package/dist/providers/workflows.d.ts +10 -5
  73. package/dist/providers/workflows.d.ts.map +1 -1
  74. package/dist/{providers-T2FQJCF6.js → providers-QF2RFB4J.js} +2 -2
  75. package/dist/public-surface/generated-manifest.d.ts +8 -8
  76. package/dist/public-surface/generated-manifest.d.ts.map +1 -1
  77. package/dist/public-surface/source.d.ts +13 -12
  78. package/dist/public-surface/source.d.ts.map +1 -1
  79. package/dist/relay/protocol.d.ts +14 -2
  80. package/dist/relay/protocol.d.ts.map +1 -1
  81. package/dist/tools/inspiredesign_run.d.ts.map +1 -1
  82. package/dist/tools/macro_resolve.d.ts.map +1 -1
  83. package/dist/tools/product_video_run.d.ts.map +1 -1
  84. package/dist/tools/research_run.d.ts.map +1 -1
  85. package/dist/tools/shopping_run.d.ts.map +1 -1
  86. package/extension/dist/canvas/canvas-runtime.js +13 -6
  87. package/extension/dist/services/ConnectionManager.js +8 -4
  88. package/extension/manifest.json +1 -1
  89. package/package.json +1 -1
  90. package/skills/opendevbrowser-best-practices/SKILL.md +6 -6
  91. package/skills/opendevbrowser-best-practices/assets/templates/skill-runtime-pack-matrix.json +1 -1
  92. package/skills/opendevbrowser-design-agent/SKILL.md +5 -0
  93. package/skills/opendevbrowser-design-agent/artifacts/design-contract-playbook.md +6 -1
  94. package/skills/opendevbrowser-design-agent/assets/templates/design-contract.v1.json +15 -1
  95. package/skills/opendevbrowser-design-agent/assets/templates/inspiredesign-advanced-brief.v1.json +72 -33
  96. package/skills/opendevbrowser-design-agent/assets/templates/reference-pattern-board.v1.json +2 -0
  97. package/dist/chunk-AVQL6WAS.js.map +0 -1
  98. package/dist/chunk-GTTYIAI7.js.map +0 -1
  99. package/dist/providers/inspiredesign-capture-mode.d.ts.map +0 -1
  100. package/dist/providers/inspiredesign-capture.d.ts.map +0 -1
  101. package/dist/providers/inspiredesign-contract.d.ts.map +0 -1
  102. /package/dist/{providers-T2FQJCF6.js.map → providers-QF2RFB4J.js.map} +0 -0
@@ -47,7 +47,7 @@ import {
47
47
  runResearchWorkflow,
48
48
  runShoppingWorkflow,
49
49
  toSnippet
50
- } from "./chunk-AVQL6WAS.js";
50
+ } from "./chunk-T3VVHJTK.js";
51
51
  import {
52
52
  ProviderRuntimeError
53
53
  } from "./chunk-FUSXMW3G.js";
@@ -3199,6 +3199,19 @@ var isExplicitShoppingExtensionRequest = (request) => {
3199
3199
  const preferredModes = request.runtimePolicy?.browser.preferredModes ?? request.preferredModes;
3200
3200
  return request.source === "shopping" && preferredModes?.length === 1 && preferredModes[0] === "extension";
3201
3201
  };
3202
+ var isExplicitSocialExtensionRequest = (request) => {
3203
+ const preferredModes = request.runtimePolicy?.browser.preferredModes ?? request.preferredModes;
3204
+ return request.source === "social" && request.runtimePolicy?.browser.forceTransport === true && preferredModes?.length === 1 && preferredModes[0] === "extension";
3205
+ };
3206
+ var shouldVerifyExtensionRequestUrl = (request) => isExplicitShoppingExtensionRequest(request) || isExplicitSocialExtensionRequest(request);
3207
+ var isRequiredExtensionSessionRequest = (request, runtimePolicy, preferredMode) => {
3208
+ if (preferredMode !== "extension") {
3209
+ return false;
3210
+ }
3211
+ const preferredModes = request.runtimePolicy?.browser.preferredModes ?? request.preferredModes;
3212
+ return runtimePolicy.browser.forceTransport === true || runtimePolicy.cookies.policy === "required" || preferredModes?.length === 1 && preferredModes[0] === "extension";
3213
+ };
3214
+ var requiresAuthenticatedExtensionSession = (runtimePolicy) => runtimePolicy.cookies.policy === "required";
3202
3215
  var shouldAttachExtensionStartUrl = (request) => request.source === "social" || request.source === "shopping";
3203
3216
  var SOCIAL_EXTENSION_MODE_ATTEMPTS = 3;
3204
3217
  var resolveSocialExtensionModeAttempts = (request, preferredMode) => preferredMode === "extension" && request.source === "social" ? SOCIAL_EXTENSION_MODE_ATTEMPTS : 1;
@@ -3301,6 +3314,29 @@ var fallbackFailure = (reasonCode, message, cookieDiagnostics, challengeOrchestr
3301
3314
  ...options.details ? options.details : {}
3302
3315
  }
3303
3316
  });
3317
+ var extensionSessionRequiredFailure = (message, cookieDiagnostics, runtimePolicy, details) => {
3318
+ const reasonMessage = `Logged-in extension session required: ${message}`;
3319
+ cookieDiagnostics.reasonCode = "auth_required";
3320
+ cookieDiagnostics.message = reasonMessage;
3321
+ return fallbackFailure("auth_required", reasonMessage, cookieDiagnostics, void 0, runtimePolicy, {
3322
+ mode: "extension",
3323
+ details: {
3324
+ ...details ?? {},
3325
+ extensionSessionRequired: true
3326
+ }
3327
+ });
3328
+ };
3329
+ var extensionTransportUnavailableFailure = (message, cookieDiagnostics, runtimePolicy, details) => {
3330
+ cookieDiagnostics.reasonCode = "env_limited";
3331
+ cookieDiagnostics.message = message;
3332
+ return fallbackFailure("env_limited", message, cookieDiagnostics, void 0, runtimePolicy, {
3333
+ mode: "extension",
3334
+ details: {
3335
+ ...details ?? {},
3336
+ extensionTransportRequired: true
3337
+ }
3338
+ });
3339
+ };
3304
3340
  var toJsonValue = (value) => {
3305
3341
  if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
3306
3342
  return value;
@@ -3364,7 +3400,7 @@ var buildFallbackChallengeOrchestration = (args2) => {
3364
3400
  mode: policy.mode,
3365
3401
  source: policy.source,
3366
3402
  ...policy.standDownReason ? { standDownReason: policy.standDownReason } : {},
3367
- helperEligibility: resolveFallbackHelperEligibility({
3403
+ helperEligibility: args2.helperEligibility ?? resolveFallbackHelperEligibility({
3368
3404
  mode: policy.mode,
3369
3405
  helperBridgeEnabled: args2.helperBridgeEnabled
3370
3406
  }),
@@ -3372,6 +3408,11 @@ var buildFallbackChallengeOrchestration = (args2) => {
3372
3408
  reason: args2.reason
3373
3409
  });
3374
3410
  };
3411
+ var NO_ACTIVE_CHALLENGE_HELPER_ELIGIBILITY = {
3412
+ allowed: false,
3413
+ reason: "No active auth or challenge blocker was detected after capture.",
3414
+ standDownReason: "helper_no_active_challenge"
3415
+ };
3375
3416
  var isPreserveEligibleBlocker = (blocker) => {
3376
3417
  return blocker?.type === "auth_required" || blocker?.type === "anti_bot_challenge";
3377
3418
  };
@@ -3771,16 +3812,20 @@ var createBrowserFallbackPort = (manager, cookieDefaults = {}, transportDefaults
3771
3812
  ensureNotAborted("mode_start");
3772
3813
  if (preferredMode === "extension") {
3773
3814
  if (!transportDefaults.extensionWsEndpoint) {
3774
- lastFailure = fallbackFailure("env_limited", "Extension fallback requires a relay endpoint.", cookieDiagnostics, void 0, runtimePolicyRecord);
3815
+ lastFailure = isRequiredExtensionSessionRequest(request, runtimePolicy, preferredMode) ? extensionTransportUnavailableFailure(
3816
+ "Extension fallback requires a relay endpoint.",
3817
+ cookieDiagnostics,
3818
+ runtimePolicyRecord
3819
+ ) : fallbackFailure("env_limited", "Extension fallback requires a relay endpoint.", cookieDiagnostics, void 0, runtimePolicyRecord);
3775
3820
  continue;
3776
3821
  }
3777
3822
  const attachOptions = shouldAttachExtensionStartUrl(request) ? { startUrl: requestUrl } : void 0;
3778
3823
  const attached = await manager.connectRelay(transportDefaults.extensionWsEndpoint, attachOptions);
3779
3824
  sessionId = attached.sessionId;
3780
- if (isExplicitShoppingExtensionRequest(request)) {
3825
+ if (shouldVerifyExtensionRequestUrl(request)) {
3781
3826
  attachedUrl = (await manager.status(sessionId)).url;
3782
3827
  navigatedDuringAttach = didExtensionAttachReachRequestUrl(requestUrl, attachedUrl);
3783
- if (isRestrictedExtensionAttachUrl(attachedUrl)) {
3828
+ if (request.source === "shopping" && isRestrictedExtensionAttachUrl(attachedUrl)) {
3784
3829
  const recovered = await reconnectExplicitShoppingExtensionSession({
3785
3830
  manager,
3786
3831
  sessionId,
@@ -3874,23 +3919,24 @@ var createBrowserFallbackPort = (manager, cookieDefaults = {}, transportDefaults
3874
3919
  "settle"
3875
3920
  )
3876
3921
  );
3877
- if (preferredMode === "extension" && isExplicitShoppingExtensionRequest(request)) {
3922
+ if (preferredMode === "extension" && shouldVerifyExtensionRequestUrl(request)) {
3878
3923
  const resolvedAttachStatus = await runWithinFallbackDeadline("status", async () => manager.status(activeSessionId));
3879
3924
  const observedUrl = normalizeExtensionAttachUrl(resolvedAttachStatus.url);
3880
3925
  if (!didExtensionAttachReachRequestUrl(requestUrl, resolvedAttachStatus.url)) {
3881
- lastFailure = fallbackFailure(
3882
- "env_limited",
3883
- "Extension fallback did not reach the requested shopping URL.",
3926
+ const details = {
3927
+ requestedUrl: requestUrl,
3928
+ ...observedUrl ? { observedUrl } : {}
3929
+ };
3930
+ lastFailure = requiresAuthenticatedExtensionSession(runtimePolicy) ? extensionSessionRequiredFailure(
3931
+ "Extension fallback did not reach the requested provider URL.",
3884
3932
  cookieDiagnostics,
3885
- void 0,
3886
3933
  runtimePolicyRecord,
3887
- {
3888
- mode: "extension",
3889
- details: {
3890
- requestedUrl: requestUrl,
3891
- ...observedUrl ? { observedUrl } : {}
3892
- }
3893
- }
3934
+ details
3935
+ ) : extensionTransportUnavailableFailure(
3936
+ "Extension fallback did not reach the requested provider URL.",
3937
+ cookieDiagnostics,
3938
+ runtimePolicyRecord,
3939
+ details
3894
3940
  );
3895
3941
  continue;
3896
3942
  }
@@ -4069,8 +4115,25 @@ var createBrowserFallbackPort = (manager, cookieDefaults = {}, transportDefaults
4069
4115
  runtimePolicy,
4070
4116
  helperBridgeEnabled,
4071
4117
  invoked: false,
4072
- reason: "Fallback capture cleared without an auth or challenge blocker, so challenge orchestration was not invoked."
4118
+ reason: "Fallback capture cleared without an auth or challenge blocker, so challenge orchestration was not invoked.",
4119
+ helperEligibility: NO_ACTIVE_CHALLENGE_HELPER_ELIGIBILITY
4073
4120
  });
4121
+ if (html.trim().length === 0) {
4122
+ lastFailure = fallbackFailure(
4123
+ request.reasonCode,
4124
+ `Browser fallback captured no HTML content at ${resolvedUrl}.`,
4125
+ cookieDiagnostics,
4126
+ challengeOrchestrationRecord,
4127
+ runtimePolicyRecord,
4128
+ {
4129
+ mode: toFallbackMode(status.mode),
4130
+ details: {
4131
+ captureDiagnostics
4132
+ }
4133
+ }
4134
+ );
4135
+ continue;
4136
+ }
4074
4137
  return {
4075
4138
  ok: true,
4076
4139
  reasonCode: request.reasonCode,
@@ -4107,7 +4170,7 @@ var createBrowserFallbackPort = (manager, cookieDefaults = {}, transportDefaults
4107
4170
  } : void 0;
4108
4171
  retryModeAttempt = preferredMode === "extension" && request.source === "social" && modeAttempt < maxModeAttempts;
4109
4172
  if (!retryModeAttempt) {
4110
- lastFailure = fallbackFailure(
4173
+ lastFailure = isRequiredExtensionSessionRequest(request, runtimePolicy, preferredMode) ? extensionTransportUnavailableFailure(message, cookieDiagnostics, runtimePolicyRecord, timeoutDetails) : fallbackFailure(
4111
4174
  "env_limited",
4112
4175
  message,
4113
4176
  cookieDiagnostics,
@@ -4212,7 +4275,7 @@ var createConfiguredProviderRuntime = (args2) => {
4212
4275
 
4213
4276
  // src/providers/runtime-bundle.ts
4214
4277
  var runtimeChallengeConfigFingerprints = /* @__PURE__ */ new WeakMap();
4215
- var fallbackPortChallengeConfigFingerprints = /* @__PURE__ */ new WeakMap();
4278
+ var fallbackPortFingerprints = /* @__PURE__ */ new WeakMap();
4216
4279
  var canReuseRuntime = (runtime, challengeFingerprint, hasInitOverride, hasExplicitChallengeConfig) => {
4217
4280
  if (!runtime || hasInitOverride) {
4218
4281
  return false;
@@ -4223,37 +4286,47 @@ var canReuseRuntime = (runtime, challengeFingerprint, hasInitOverride, hasExplic
4223
4286
  }
4224
4287
  return fingerprint === challengeFingerprint;
4225
4288
  };
4226
- var canReuseFallbackPort = (fallbackPort, challengeFingerprint) => {
4289
+ var canReuseFallbackPort = (fallbackPort, fingerprint) => {
4227
4290
  if (!fallbackPort) {
4228
4291
  return false;
4229
4292
  }
4230
- const fingerprint = fallbackPortChallengeConfigFingerprints.get(fallbackPort);
4231
- return fingerprint === void 0 || fingerprint === challengeFingerprint;
4293
+ const currentFingerprint = fallbackPortFingerprints.get(fallbackPort);
4294
+ if (currentFingerprint === void 0) {
4295
+ return !fingerprint.includes('"extensionWsEndpoint":"ws://');
4296
+ }
4297
+ return currentFingerprint === fingerprint;
4232
4298
  };
4233
4299
  var resolveFallbackTransportConfig = (config) => config && typeof config.relayPort === "number" && config.relayPort > 0 && config.relayToken !== false ? { extensionWsEndpoint: `ws://127.0.0.1:${config.relayPort}` } : {};
4300
+ var fallbackPortFingerprint = (challengeFingerprint, transportConfig) => JSON.stringify({
4301
+ challengeFingerprint,
4302
+ extensionWsEndpoint: transportConfig.extensionWsEndpoint ?? null
4303
+ });
4234
4304
  var createProviderRuntimeBundle = (args2) => {
4235
4305
  const challengeConfig = resolveEffectiveChallengeConfig(args2.config, args2.challengeConfig);
4236
4306
  const challengeFingerprint = challengeConfig ? JSON.stringify(challengeConfig) : null;
4237
- const browserFallbackPort = canReuseFallbackPort(args2.browserFallbackPort, challengeFingerprint) ? args2.browserFallbackPort : createBrowserFallbackPort(
4307
+ const transportConfig = resolveFallbackTransportConfig(args2.config);
4308
+ const fallbackFingerprint = fallbackPortFingerprint(challengeFingerprint, transportConfig);
4309
+ const challengeOrchestrator = args2.challengeOrchestrator ?? (challengeConfig ? new ChallengeOrchestrator(challengeConfig) : void 0);
4310
+ const browserFallbackPort = canReuseFallbackPort(args2.browserFallbackPort, fallbackFingerprint) ? args2.browserFallbackPort : createBrowserFallbackPort(
4238
4311
  args2.manager,
4239
4312
  {
4240
4313
  policy: args2.config?.providers?.cookiePolicy,
4241
4314
  source: args2.config?.providers?.cookieSource
4242
4315
  },
4243
- resolveFallbackTransportConfig(args2.config),
4244
- args2.challengeOrchestrator,
4316
+ transportConfig,
4317
+ challengeOrchestrator,
4245
4318
  challengeConfig?.mode ?? "browser_with_helper",
4246
4319
  challengeConfig?.optionalComputerUseBridge.enabled ?? true
4247
4320
  );
4248
4321
  if (browserFallbackPort && browserFallbackPort !== args2.browserFallbackPort) {
4249
- fallbackPortChallengeConfigFingerprints.set(browserFallbackPort, challengeFingerprint);
4322
+ fallbackPortFingerprints.set(browserFallbackPort, fallbackFingerprint);
4250
4323
  }
4251
4324
  const providerRuntime = createConfiguredProviderRuntime({
4252
4325
  config: args2.config,
4253
4326
  manager: args2.manager,
4254
4327
  browserFallbackPort,
4255
4328
  challengeConfig,
4256
- challengeOrchestrator: args2.challengeOrchestrator,
4329
+ challengeOrchestrator,
4257
4330
  init: args2.init
4258
4331
  });
4259
4332
  runtimeChallengeConfigFingerprints.set(
@@ -21733,6 +21806,7 @@ var APPROVED_LIBRARY_ENTRIES = {
21733
21806
  motion: new Set(PROJECT_DEFAULT_LIBRARY_POLICY.motion),
21734
21807
  threeD: new Set(PROJECT_DEFAULT_LIBRARY_POLICY.threeD)
21735
21808
  };
21809
+ var UNSUPPORTED_RUNTIME_LIBRARY_POLICY_KEYS = ["motion", "threeD"];
21736
21810
  var PROJECT_DEFAULT_RUNTIME_BUDGETS = {
21737
21811
  defaultLivePreviewLimit: 2,
21738
21812
  maxPinnedFullPreviewExtra: 1,
@@ -22857,6 +22931,52 @@ function requirePlanEnumArray(record, key, path7, allowedValues, allowedSet, iss
22857
22931
  }
22858
22932
  return normalized;
22859
22933
  }
22934
+ function optionalPlanStringArray(record, key, path7, issues) {
22935
+ const value = record[key];
22936
+ if (value === void 0) {
22937
+ return void 0;
22938
+ }
22939
+ if (!Array.isArray(value)) {
22940
+ pushGenerationPlanIssue(issues, {
22941
+ path: path7,
22942
+ code: "invalid_type",
22943
+ message: `${path7} must include only non-empty strings.`,
22944
+ expected: "string[]",
22945
+ received: clone(value)
22946
+ });
22947
+ return void 0;
22948
+ }
22949
+ const strings = value.map((entry) => typeof entry === "string" ? entry.trim() : "").filter(Boolean);
22950
+ const normalized = uniqueStrings(strings);
22951
+ if (strings.length !== value.length || normalized.length === 0) {
22952
+ pushGenerationPlanIssue(issues, {
22953
+ path: path7,
22954
+ code: "invalid_type",
22955
+ message: `${path7} must include only non-empty strings.`,
22956
+ expected: "string[]",
22957
+ received: clone(value)
22958
+ });
22959
+ return void 0;
22960
+ }
22961
+ return normalized;
22962
+ }
22963
+ function optionalPlanRecord(record, key, path7, issues) {
22964
+ const value = record[key];
22965
+ if (value === void 0) {
22966
+ return void 0;
22967
+ }
22968
+ if (isRecord6(value)) {
22969
+ return clone(value);
22970
+ }
22971
+ pushGenerationPlanIssue(issues, {
22972
+ path: path7,
22973
+ code: "invalid_type",
22974
+ message: `${path7} must be an object.`,
22975
+ expected: "object",
22976
+ received: clone(value)
22977
+ });
22978
+ return void 0;
22979
+ }
22860
22980
  function requirePositiveNumber(record, key, path7, issues) {
22861
22981
  const value = record[key];
22862
22982
  if (typeof value === "number" && Number.isFinite(value) && value > 0) {
@@ -23015,6 +23135,9 @@ function validateGenerationPlan(plan) {
23015
23135
  issues
23016
23136
  ) : null;
23017
23137
  const maxInteractionLatencyMs = validationTargets ? requirePositiveNumber(validationTargets, "maxInteractionLatencyMs", "validationTargets.maxInteractionLatencyMs", issues) : null;
23138
+ const interactionMoments = optionalPlanStringArray(plan, "interactionMoments", "interactionMoments", issues);
23139
+ const materialEffects = optionalPlanStringArray(plan, "materialEffects", "materialEffects", issues);
23140
+ const designVectors = optionalPlanRecord(plan, "designVectors", "designVectors", issues);
23018
23141
  if (issues.length > 0 || missing.length > 0) {
23019
23142
  return {
23020
23143
  ok: false,
@@ -23063,7 +23186,10 @@ function validateGenerationPlan(plan) {
23063
23186
  requiredThemes,
23064
23187
  browserValidation,
23065
23188
  maxInteractionLatencyMs
23066
- }
23189
+ },
23190
+ ...interactionMoments ? { interactionMoments } : {},
23191
+ ...materialEffects ? { materialEffects } : {},
23192
+ ...designVectors ? { designVectors } : {}
23067
23193
  }
23068
23194
  };
23069
23195
  }
@@ -23118,6 +23244,8 @@ function buildGovernanceBlockStates(document2) {
23118
23244
  if (isNonEmptyRecord(block)) {
23119
23245
  if (key === "generationPlan") {
23120
23246
  status = assessGenerationPlan(block).status === "invalid" ? "invalid" : "present";
23247
+ } else if (key === "libraryPolicy" && hasUnsupportedRuntimeLanePolicy(document2)) {
23248
+ status = "invalid";
23121
23249
  } else {
23122
23250
  const inheritedDefault = OPTIONAL_INHERITED_KEYS.has(key) ? inheritedDefaultForGovernanceKey(key) : null;
23123
23251
  status = inheritedDefault && stableStringify(block) === stableStringify(inheritedDefault) ? "inherited" : "present";
@@ -23202,7 +23330,13 @@ function evaluateCanvasWarnings(document2, options = {}) {
23202
23330
  warnings.push(buildWarning("responsive-mismatch", "Viewport coverage is incomplete for desktop, tablet, and mobile previews.", { auditId: "CANVAS-02" }));
23203
23331
  }
23204
23332
  if (hasDisallowedLibrary(document2)) {
23205
- warnings.push(buildWarning("library-policy-violation", "Library policy references a non-approved canvas library.", { auditId: "CANVAS-04", severity: "error" }));
23333
+ const runtimeLaneViolations = runtimeLanePolicyViolations(resolveCanvasLibraryPolicy(document2));
23334
+ const details = runtimeLaneViolations.length > 0 ? { runtimeLaneViolations } : void 0;
23335
+ warnings.push(buildWarning("library-policy-violation", "Library policy references a non-approved canvas library.", {
23336
+ auditId: "CANVAS-04",
23337
+ severity: "error",
23338
+ ...details ? { details } : {}
23339
+ }));
23206
23340
  }
23207
23341
  if (hasIconPolicyViolation(document2)) {
23208
23342
  warnings.push(buildWarning("icon-policy-violation", "Icon policy references a non-approved icon family.", { auditId: "CANVAS-04", severity: "error" }));
@@ -23263,7 +23397,12 @@ function evaluateCanvasWarnings(document2, options = {}) {
23263
23397
  }
23264
23398
  function missingRequiredSaveBlocks(document2) {
23265
23399
  const states = buildGovernanceBlockStates(document2);
23266
- return REQUIRED_BEFORE_SAVE_KEYS.filter((key) => key === "generationPlan" ? states[key].status === "missing" || states[key].status === "invalid" : states[key].status === "missing");
23400
+ return REQUIRED_BEFORE_SAVE_KEYS.filter((key) => {
23401
+ if (key === "generationPlan" || key === "libraryPolicy") {
23402
+ return states[key].status === "missing" || states[key].status === "invalid";
23403
+ }
23404
+ return states[key].status === "missing";
23405
+ });
23267
23406
  }
23268
23407
  function validateCanvasSave(document2) {
23269
23408
  const missingBlocks = missingRequiredSaveBlocks(document2);
@@ -23299,6 +23438,20 @@ function hasDisallowedLibrary(document2) {
23299
23438
  const policy = resolveCanvasLibraryPolicy(document2);
23300
23439
  return Object.entries(policy).some(([category, entries]) => entries.some((entry) => !APPROVED_LIBRARY_ENTRIES[category].has(entry)));
23301
23440
  }
23441
+ function runtimeLanePolicyViolations(policy) {
23442
+ return UNSUPPORTED_RUNTIME_LIBRARY_POLICY_KEYS.map((category) => ({ category, entries: policy[category] })).filter((violation) => violation.entries.length > 0);
23443
+ }
23444
+ function hasUnsupportedRuntimeLanePolicy(document2) {
23445
+ return runtimeLanePolicyViolations(resolveCanvasLibraryPolicy(document2)).length > 0;
23446
+ }
23447
+ function assertNoUnsupportedRuntimeLanePolicy(document2) {
23448
+ const violations = runtimeLanePolicyViolations(resolveCanvasLibraryPolicy(document2));
23449
+ if (violations.length === 0) {
23450
+ return;
23451
+ }
23452
+ const paths = violations.map(({ category }) => `libraryPolicy.${category}`).join(", ");
23453
+ throw new Error(`${paths} must stay empty. Put shader, WebGL, Spline, and advanced motion cues in motionSystem or generationPlan.designVectors as advisory metadata only.`);
23454
+ }
23302
23455
  function hasIconPolicyViolation(document2) {
23303
23456
  const iconRoles = readCanvasIconRoles(document2);
23304
23457
  return Object.values(iconRoles).filter((entry) => Boolean(entry)).some((entry) => !APPROVED_LIBRARY_ENTRIES.icons.has(entry));
@@ -23629,6 +23782,7 @@ var CanvasDocumentStore = class {
23629
23782
  }
23630
23783
  replaceDocument(document2, revision, origin) {
23631
23784
  const nextDocument = normalizeCanvasDocument(document2);
23785
+ assertNoUnsupportedRuntimeLanePolicy(nextDocument);
23632
23786
  nextDocument.updatedAt = nowIso();
23633
23787
  this.ydoc.transact(() => {
23634
23788
  clearYMap(this.root);
@@ -30131,7 +30285,7 @@ function optionalString4(value) {
30131
30285
  return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
30132
30286
  }
30133
30287
 
30134
- // src/browser/canvas-manager.ts
30288
+ // src/canvas/guidance.ts
30135
30289
  var PREPLAN_CANVAS_GUIDANCE = {
30136
30290
  recommendedNextCommands: ["canvas.plan.set"],
30137
30291
  reason: "Handshake is complete. Submit a complete generationPlan before mutation."
@@ -30172,6 +30326,30 @@ var CANVAS_GUIDANCE_BY_COMMAND = {
30172
30326
  "canvas.document.save": PERSISTED_CANVAS_GUIDANCE,
30173
30327
  "canvas.document.export": EXPORTED_CANVAS_GUIDANCE
30174
30328
  };
30329
+ var CANVAS_REQUIRED_COMMANDS_BY_BLOCKER = {
30330
+ plan_required: ["canvas.plan.set"],
30331
+ generation_plan_invalid: ["canvas.plan.set", "canvas.plan.get"],
30332
+ revision_conflict: ["canvas.document.load"],
30333
+ policy_violation: ["canvas.plan.get", "canvas.document.load"],
30334
+ unsupported_target: ["canvas.session.status"],
30335
+ lease_reclaim_required: ["canvas.session.status"]
30336
+ };
30337
+ var cloneCanvasGuidance = (guidance) => ({
30338
+ recommendedNextCommands: [...guidance.recommendedNextCommands],
30339
+ reason: guidance.reason
30340
+ });
30341
+ var buildCanvasCommandGuidance = (input) => {
30342
+ if (input.planStatus === "invalid") {
30343
+ return cloneCanvasGuidance(INVALID_PLAN_CANVAS_GUIDANCE);
30344
+ }
30345
+ if (input.planStatus !== "accepted") {
30346
+ return cloneCanvasGuidance(PREPLAN_CANVAS_GUIDANCE);
30347
+ }
30348
+ return cloneCanvasGuidance(CANVAS_GUIDANCE_BY_COMMAND[input.command] ?? PLAN_ACCEPTED_CANVAS_GUIDANCE);
30349
+ };
30350
+ var getCanvasRequiredNextCommands = (code) => [...CANVAS_REQUIRED_COMMANDS_BY_BLOCKER[code]];
30351
+
30352
+ // src/browser/canvas-manager.ts
30175
30353
  function resolveGenerationPlanState(plan) {
30176
30354
  const assessment = assessGenerationPlan(plan);
30177
30355
  if (assessment.status === "accepted") {
@@ -30338,6 +30516,7 @@ var CanvasManager = class {
30338
30516
  repoRoot,
30339
30517
  documentRepoPath: repoPath ?? null,
30340
30518
  leaseId,
30519
+ legacyLifecycleEventsTrusted: true,
30341
30520
  mode,
30342
30521
  usesCanvasRelay: false,
30343
30522
  store: new CanvasDocumentStore(document2),
@@ -30379,6 +30558,9 @@ var CanvasManager = class {
30379
30558
  attachMode
30380
30559
  );
30381
30560
  session.leaseId = attached.leaseId;
30561
+ if (attachMode === "lease_reclaim") {
30562
+ session.legacyLifecycleEventsTrusted = false;
30563
+ }
30382
30564
  return {
30383
30565
  clientId: attached.clientId,
30384
30566
  attachMode: attached.attachMode,
@@ -32114,14 +32296,10 @@ var CanvasManager = class {
32114
32296
  };
32115
32297
  }
32116
32298
  buildCanvasGuidance(session, command) {
32117
- if (session.planStatus === "invalid") {
32118
- return cloneCanvasGuidance(INVALID_PLAN_CANVAS_GUIDANCE);
32119
- }
32120
- if (session.planStatus !== "accepted") {
32121
- return cloneCanvasGuidance(PREPLAN_CANVAS_GUIDANCE);
32122
- }
32123
- const guidance = CANVAS_GUIDANCE_BY_COMMAND[command] ?? PLAN_ACCEPTED_CANVAS_GUIDANCE;
32124
- return cloneCanvasGuidance(guidance);
32299
+ return buildCanvasCommandGuidance({
32300
+ planStatus: session.planStatus,
32301
+ command
32302
+ });
32125
32303
  }
32126
32304
  buildSessionSummary(session) {
32127
32305
  const document2 = session.store.getDocument();
@@ -32352,7 +32530,7 @@ var CanvasManager = class {
32352
32530
  const blocker = {
32353
32531
  code: "plan_required",
32354
32532
  blockingCommand: command,
32355
- requiredNextCommands: ["canvas.plan.set"],
32533
+ requiredNextCommands: getCanvasRequiredNextCommands("plan_required"),
32356
32534
  latestRevision: session.store.getRevision(),
32357
32535
  message: "generationPlan must be accepted before mutation."
32358
32536
  };
@@ -32362,7 +32540,7 @@ var CanvasManager = class {
32362
32540
  const blocker = {
32363
32541
  code: "generation_plan_invalid",
32364
32542
  blockingCommand: command,
32365
- requiredNextCommands: ["canvas.plan.set", "canvas.plan.get"],
32543
+ requiredNextCommands: getCanvasRequiredNextCommands("generation_plan_invalid"),
32366
32544
  latestRevision: session.store.getRevision(),
32367
32545
  message: this.describeGenerationPlanFailure(missingFields, issues)
32368
32546
  };
@@ -32380,7 +32558,7 @@ var CanvasManager = class {
32380
32558
  const blocker = {
32381
32559
  code: "revision_conflict",
32382
32560
  blockingCommand: command,
32383
- requiredNextCommands: ["canvas.document.load"],
32561
+ requiredNextCommands: getCanvasRequiredNextCommands("revision_conflict"),
32384
32562
  latestRevision: session.store.getRevision(),
32385
32563
  message: "The canvas document revision changed before this patch batch was applied."
32386
32564
  };
@@ -32390,7 +32568,7 @@ var CanvasManager = class {
32390
32568
  const blocker = {
32391
32569
  code: "policy_violation",
32392
32570
  blockingCommand: command,
32393
- requiredNextCommands: ["canvas.plan.get", "canvas.document.load"],
32571
+ requiredNextCommands: getCanvasRequiredNextCommands("policy_violation"),
32394
32572
  latestRevision: session.store.getRevision(),
32395
32573
  message: `Required save governance blocks are missing: ${missingBlocks.join(", ")}.`
32396
32574
  };
@@ -32408,7 +32586,7 @@ var CanvasManager = class {
32408
32586
  const blocker = {
32409
32587
  code: "unsupported_target",
32410
32588
  blockingCommand: command,
32411
- requiredNextCommands: ["canvas.session.status"],
32589
+ requiredNextCommands: getCanvasRequiredNextCommands("unsupported_target"),
32412
32590
  latestRevision: session.store.getRevision(),
32413
32591
  message: `Canvas target is unavailable: ${targetId}.`
32414
32592
  };
@@ -32425,7 +32603,7 @@ var CanvasManager = class {
32425
32603
  const blocker = {
32426
32604
  code: "lease_reclaim_required",
32427
32605
  blockingCommand: "canvas.session.status",
32428
- requiredNextCommands: ["canvas.session.status"],
32606
+ requiredNextCommands: getCanvasRequiredNextCommands("lease_reclaim_required"),
32429
32607
  latestRevision: session.store.getRevision(),
32430
32608
  message: "The canvas lease was reclaimed or replaced."
32431
32609
  };
@@ -32479,13 +32657,13 @@ var CanvasManager = class {
32479
32657
  const blocker = session.planStatus === "invalid" ? {
32480
32658
  code: "generation_plan_invalid",
32481
32659
  blockingCommand: "canvas.feedback.poll",
32482
- requiredNextCommands: ["canvas.plan.set", "canvas.plan.get"],
32660
+ requiredNextCommands: getCanvasRequiredNextCommands("generation_plan_invalid"),
32483
32661
  latestRevision: session.store.getRevision(),
32484
32662
  message: this.describeGenerationPlanFailure([], session.planIssues)
32485
32663
  } : {
32486
32664
  code: "plan_required",
32487
32665
  blockingCommand: "canvas.feedback.poll",
32488
- requiredNextCommands: ["canvas.plan.set"],
32666
+ requiredNextCommands: getCanvasRequiredNextCommands("plan_required"),
32489
32667
  latestRevision: session.store.getRevision(),
32490
32668
  message: "generationPlan must be accepted before the live design loop is ready."
32491
32669
  };
@@ -32824,8 +33002,16 @@ var CanvasManager = class {
32824
33002
  if (!session) {
32825
33003
  return;
32826
33004
  }
33005
+ const isLifecycleEvent = event.event === "canvas_session_closed" || event.event === "canvas_session_expired";
32827
33006
  const payload = isRecord14(event.payload) ? event.payload : null;
32828
33007
  if (!payload) {
33008
+ if (isLifecycleEvent && event.payload === void 0 && session.legacyLifecycleEventsTrusted) {
33009
+ this.completeFeedbackSubscriptions(session, event.event === "canvas_session_closed" ? "session_closed" : "document_unloaded");
33010
+ this.sessionSyncManager.removeSession(session.canvasSessionId);
33011
+ this.codeSyncManager.disposeSession(session.canvasSessionId);
33012
+ this.sessions.delete(session.canvasSessionId);
33013
+ this.disconnectCanvasClientIfIdle();
33014
+ }
32829
33015
  return;
32830
33016
  }
32831
33017
  if (event.event === "canvas_target_closed") {
@@ -32844,7 +33030,11 @@ var CanvasManager = class {
32844
33030
  }
32845
33031
  return;
32846
33032
  }
32847
- if (event.event === "canvas_session_closed" || event.event === "canvas_session_expired") {
33033
+ if (isLifecycleEvent) {
33034
+ const eventLeaseId = optionalString5(payload.leaseId);
33035
+ if (eventLeaseId !== session.leaseId) {
33036
+ return;
33037
+ }
32848
33038
  this.completeFeedbackSubscriptions(session, event.event === "canvas_session_closed" ? "session_closed" : "document_unloaded");
32849
33039
  this.sessionSyncManager.removeSession(session.canvasSessionId);
32850
33040
  this.codeSyncManager.disposeSession(session.canvasSessionId);
@@ -34221,12 +34411,6 @@ function attachDetails(error, details) {
34221
34411
  Object.assign(error, details);
34222
34412
  return error;
34223
34413
  }
34224
- function cloneCanvasGuidance(guidance) {
34225
- return {
34226
- recommendedNextCommands: [...guidance.recommendedNextCommands],
34227
- reason: guidance.reason
34228
- };
34229
- }
34230
34414
 
34231
34415
  // src/relay/relay-server.ts
34232
34416
  import { createServer } from "http";
@@ -36353,7 +36537,7 @@ function getBoolean(value) {
36353
36537
  return typeof value === "boolean" ? value : null;
36354
36538
  }
36355
36539
 
36356
- // src/providers/inspiredesign-capture.ts
36540
+ // src/inspiredesign/capture.ts
36357
36541
  var INSPIREDESIGN_CAPTURE_TIMEOUT_MS = 3e4;
36358
36542
  var INSPIREDESIGN_CAPTURE_MAX_CHARS = 12e3;
36359
36543
  var ACTIVE_SESSION_COOKIE_REUSE_UNAVAILABLE_MESSAGE = "Deep capture only honors configured provider cookie sources; active session cookies are not reused.";
@@ -36684,6 +36868,10 @@ var readTargetedSocialPlatform = (providerId) => {
36684
36868
  return "bluesky";
36685
36869
  case "social/reddit":
36686
36870
  return "reddit";
36871
+ case "social/facebook":
36872
+ return "facebook";
36873
+ case "social/threads":
36874
+ return "threads";
36687
36875
  default:
36688
36876
  return null;
36689
36877
  }
@@ -36834,7 +37022,8 @@ var buildRunOptions = (resolution, overrides) => {
36834
37022
  return {
36835
37023
  source,
36836
37024
  ...providerId ? { providerIds: [providerId] } : {},
36837
- ...overrides?.challengeAutomationMode ? { challengeAutomationMode: overrides.challengeAutomationMode } : {}
37025
+ ...overrides?.challengeAutomationMode ? { challengeAutomationMode: overrides.challengeAutomationMode } : {},
37026
+ ...overrides?.browserMode ? { runtimePolicy: { browserMode: overrides.browserMode } } : {}
36838
37027
  };
36839
37028
  };
36840
37029
  var executeMacroResolution = async (resolution, runtime, overrides) => {
@@ -36922,7 +37111,10 @@ var executeMacroWithRuntime = async (args2) => {
36922
37111
  await executeMacroResolution(
36923
37112
  args2.resolution,
36924
37113
  runtime,
36925
- args2.challengeAutomationMode ? { challengeAutomationMode: args2.challengeAutomationMode } : void 0
37114
+ args2.challengeAutomationMode || args2.browserMode ? {
37115
+ ...args2.browserMode ? { browserMode: args2.browserMode } : {},
37116
+ ...args2.challengeAutomationMode ? { challengeAutomationMode: args2.challengeAutomationMode } : {}
37117
+ } : void 0
36926
37118
  )
36927
37119
  );
36928
37120
  };
@@ -37581,7 +37773,7 @@ async function handleDaemonCommand(core, request) {
37581
37773
  return core.manager.snapshot(
37582
37774
  requireString3(params2.sessionId, "sessionId"),
37583
37775
  requireSnapshotMode2(params2.mode),
37584
- optionalNumber(params2.maxChars, "maxChars") ?? 16e3,
37776
+ optionalPositiveInteger2(params2.maxChars, "maxChars") ?? 16e3,
37585
37777
  optionalString6(params2.cursor),
37586
37778
  targetId
37587
37779
  );
@@ -37592,7 +37784,7 @@ async function handleDaemonCommand(core, request) {
37592
37784
  manager: core.manager,
37593
37785
  sessionId: requireString3(params2.sessionId, "sessionId"),
37594
37786
  targetId: optionalString6(params2.targetId),
37595
- maxChars: optionalNumber(params2.maxChars, "maxChars") ?? core.config.snapshot.maxChars,
37787
+ maxChars: optionalPositiveInteger2(params2.maxChars, "maxChars") ?? core.config.snapshot.maxChars,
37596
37788
  cursor: optionalString6(params2.cursor)
37597
37789
  });
37598
37790
  case "nav.reviewDesktop":
@@ -37720,7 +37912,7 @@ async function handleDaemonCommand(core, request) {
37720
37912
  return core.manager.domGetHtml(
37721
37913
  requireString3(params2.sessionId, "sessionId"),
37722
37914
  requireString3(params2.ref, "ref"),
37723
- optionalNumber(params2.maxChars, "maxChars") ?? 8e3,
37915
+ optionalPositiveInteger2(params2.maxChars, "maxChars") ?? 8e3,
37724
37916
  optionalString6(params2.targetId)
37725
37917
  );
37726
37918
  case "dom.getText":
@@ -37728,7 +37920,7 @@ async function handleDaemonCommand(core, request) {
37728
37920
  return core.manager.domGetText(
37729
37921
  requireString3(params2.sessionId, "sessionId"),
37730
37922
  requireString3(params2.ref, "ref"),
37731
- optionalNumber(params2.maxChars, "maxChars") ?? 8e3,
37923
+ optionalPositiveInteger2(params2.maxChars, "maxChars") ?? 8e3,
37732
37924
  optionalString6(params2.targetId)
37733
37925
  );
37734
37926
  case "dom.getAttr":
@@ -37852,15 +38044,15 @@ async function handleDaemonCommand(core, request) {
37852
38044
  await authorizeSessionCommand(core, params2, request.name, bindingId);
37853
38045
  return core.manager.consolePoll(
37854
38046
  requireString3(params2.sessionId, "sessionId"),
37855
- optionalNumber(params2.sinceSeq, "sinceSeq"),
37856
- optionalNumber(params2.max, "max") ?? 50
38047
+ optionalNonNegativeInteger(params2.sinceSeq, "sinceSeq"),
38048
+ optionalPositiveInteger2(params2.max, "max") ?? 50
37857
38049
  );
37858
38050
  case "devtools.networkPoll":
37859
38051
  await authorizeSessionCommand(core, params2, request.name, bindingId);
37860
38052
  return core.manager.networkPoll(
37861
38053
  requireString3(params2.sessionId, "sessionId"),
37862
- optionalNumber(params2.sinceSeq, "sinceSeq"),
37863
- optionalNumber(params2.max, "max") ?? 50
38054
+ optionalNonNegativeInteger(params2.sinceSeq, "sinceSeq"),
38055
+ optionalPositiveInteger2(params2.max, "max") ?? 50
37864
38056
  );
37865
38057
  case "devtools.debugTraceSnapshot": {
37866
38058
  await authorizeSessionCommand(core, params2, request.name, bindingId);
@@ -37967,21 +38159,32 @@ async function handleDaemonCommand(core, request) {
37967
38159
  count: cookies.length
37968
38160
  };
37969
38161
  }
37970
- case "macro.resolve":
38162
+ case "macro.resolve": {
38163
+ const execute = optionalBoolean2(params2.execute) ?? false;
38164
+ const browserMode = optionalWorkflowBrowserMode(params2.browserMode);
38165
+ const challengeAutomationMode = optionalChallengeAutomationMode(params2.challengeAutomationMode);
38166
+ if (!execute && browserMode) {
38167
+ throw new Error("browserMode requires execute=true for macro resolution");
38168
+ }
38169
+ if (!execute && challengeAutomationMode) {
38170
+ throw new Error("challengeAutomationMode requires execute=true for macro resolution");
38171
+ }
37971
38172
  return resolveMacroExpression(
37972
38173
  {
37973
38174
  expression: requireString3(params2.expression, "expression"),
37974
38175
  defaultProvider: optionalString6(params2.defaultProvider),
37975
38176
  includeCatalog: optionalBoolean2(params2.includeCatalog) ?? false,
37976
- execute: optionalBoolean2(params2.execute) ?? false,
38177
+ execute,
37977
38178
  timeoutMs: optionalNumber(params2.timeoutMs, "timeoutMs"),
37978
- challengeAutomationMode: optionalChallengeAutomationMode(params2.challengeAutomationMode)
38179
+ browserMode,
38180
+ challengeAutomationMode
37979
38181
  },
37980
38182
  core.config,
37981
38183
  core.manager,
37982
38184
  core.browserFallbackPort,
37983
38185
  core.providerRuntime
37984
38186
  );
38187
+ }
37985
38188
  case "research.run":
37986
38189
  return runResearchWorkflow(
37987
38190
  createDaemonWorkflowRuntime(core),
@@ -37998,6 +38201,7 @@ async function handleDaemonCommand(core, request) {
37998
38201
  timeoutMs: optionalNumber(params2.timeoutMs, "timeoutMs"),
37999
38202
  outputDir: optionalString6(params2.outputDir),
38000
38203
  ttlHours: optionalNumber(params2.ttlHours, "ttlHours"),
38204
+ browserMode: optionalWorkflowBrowserMode(params2.browserMode),
38001
38205
  useCookies: optionalBoolean2(params2.useCookies),
38002
38206
  challengeAutomationMode: optionalChallengeAutomationMode(params2.challengeAutomationMode),
38003
38207
  cookiePolicyOverride: optionalCookiePolicy(params2.cookiePolicyOverride)
@@ -38035,6 +38239,7 @@ async function handleDaemonCommand(core, request) {
38035
38239
  timeoutMs: inspiredesignTimeoutMs,
38036
38240
  outputDir: optionalString6(params2.outputDir),
38037
38241
  ttlHours: optionalNumber(params2.ttlHours, "ttlHours"),
38242
+ browserMode: optionalWorkflowBrowserMode(params2.browserMode),
38038
38243
  useCookies: optionalBoolean2(params2.useCookies),
38039
38244
  challengeAutomationMode: optionalChallengeAutomationMode(params2.challengeAutomationMode),
38040
38245
  cookiePolicyOverride: optionalCookiePolicy(params2.cookiePolicyOverride)
@@ -38061,6 +38266,7 @@ async function handleDaemonCommand(core, request) {
38061
38266
  output_dir: optionalString6(params2.output_dir),
38062
38267
  ttl_hours: optionalNumber(params2.ttl_hours, "ttl_hours"),
38063
38268
  timeoutMs: productVideoTimeoutMs,
38269
+ browserMode: optionalWorkflowBrowserMode(params2.browserMode),
38064
38270
  useCookies: optionalBoolean2(params2.useCookies),
38065
38271
  challengeAutomationMode: optionalChallengeAutomationMode(params2.challengeAutomationMode),
38066
38272
  cookiePolicyOverride: optionalCookiePolicy(params2.cookiePolicyOverride)
@@ -38726,6 +38932,15 @@ function optionalPositiveInteger2(value, label) {
38726
38932
  }
38727
38933
  throw new Error(`Invalid ${label}`);
38728
38934
  }
38935
+ function optionalNonNegativeInteger(value, label) {
38936
+ if (typeof value === "undefined") {
38937
+ return void 0;
38938
+ }
38939
+ if (typeof value === "number" && Number.isInteger(value) && value >= 0) {
38940
+ return value;
38941
+ }
38942
+ throw new Error(`Invalid ${label}`);
38943
+ }
38729
38944
  function requirePointerPoint(value, label) {
38730
38945
  const point = requireRecord2(value, label);
38731
38946
  return {
@@ -39012,6 +39227,7 @@ async function resolveMacroExpression(options, config, manager, browserFallbackP
39012
39227
  manager,
39013
39228
  browserFallbackPort,
39014
39229
  timeoutMs: options.timeoutMs,
39230
+ browserMode: options.browserMode,
39015
39231
  challengeAutomationMode: options.challengeAutomationMode
39016
39232
  });
39017
39233
  const handoff = buildMacroResolveSuccessHandoff({
@@ -40039,7 +40255,7 @@ var sleep3 = async (delayMs) => {
40039
40255
  await new Promise((resolve9) => setTimeout(resolve9, delayMs));
40040
40256
  };
40041
40257
  var requiresConfiguredRecovery = (name) => {
40042
- return name === "canvas.execute";
40258
+ return name === "canvas.execute" || name === "inspiredesign.run";
40043
40259
  };
40044
40260
  var getConfiguredDaemonConnection = () => {
40045
40261
  const config = loadGlobalConfig();
@@ -40394,8 +40610,8 @@ var onboarding_metadata_default = {
40394
40610
  skillList: "opendevbrowser_skill_list",
40395
40611
  skillLoad: 'opendevbrowser_skill_load opendevbrowser-best-practices "quick start"',
40396
40612
  validatedLanes: 'opendevbrowser_skill_load opendevbrowser-best-practices "validated capability lanes"',
40397
- validatedResearch: 'npx opendevbrowser research run --topic "Chrome extension debugging workflows" --days 30 --source-selection auto --mode json --output-format json',
40398
- validatedShopping: 'npx opendevbrowser shopping run --query "wireless ergonomic mouse" --providers shopping/bestbuy,shopping/ebay --budget 150 --browser-mode managed --mode json --output-format json',
40613
+ validatedResearch: 'npx opendevbrowser research run --topic "Chrome extension debugging workflows" --days 30 --source-selection auto --browser-mode managed --mode json --output-format json',
40614
+ validatedShopping: 'npx opendevbrowser shopping run --query "wireless ergonomic mouse" --providers shopping/bestbuy,shopping/ebay --budget 150 --browser-mode managed --use-cookies --challenge-automation-mode browser_with_helper --mode json --output-format json',
40399
40615
  computerUseEntry: 'npx opendevbrowser research run --topic "account recovery flow" --source-selection auto --challenge-automation-mode browser --mode json --output-format json',
40400
40616
  happyPath: "npx opendevbrowser launch --no-extension --headless --start-url https://example.com --output-format json"
40401
40617
  },
@@ -40539,7 +40755,7 @@ var DEFAULT_WORKFLOW_TRANSPORT_TIMEOUT_MS = 12e4;
40539
40755
  // src/public-surface/generated-manifest.ts
40540
40756
  var PUBLIC_SURFACE_MANIFEST = {
40541
40757
  "schemaVersion": "2026-04-04",
40542
- "generatedAt": "2026-04-20T16:29:04.426Z",
40758
+ "generatedAt": "2026-04-30T02:27:58.736Z",
40543
40759
  "cli": {
40544
40760
  "groups": [
40545
40761
  {
@@ -40737,7 +40953,7 @@ var PUBLIC_SURFACE_MANIFEST = {
40737
40953
  },
40738
40954
  {
40739
40955
  "name": "update",
40740
- "description": "Clear cached plugin and refresh managed skill packs",
40956
+ "description": "Repair cached plugin pins and refresh managed skill packs",
40741
40957
  "usage": "npx opendevbrowser update [--global|--local] [--skills-global|--skills-local|--no-skills]",
40742
40958
  "flags": [
40743
40959
  "--global",
@@ -40965,7 +41181,7 @@ var PUBLIC_SURFACE_MANIFEST = {
40965
41181
  "--timeout-ms"
40966
41182
  ],
40967
41183
  "examples": [
40968
- "npx opendevbrowser status-capabilities --session-id s1 --target-id page-1 --challenge-automation-mode browser --timeout-ms 30000 --output-format json"
41184
+ "npx opendevbrowser status-capabilities --session-id s1 --target-id page-1 --challenge-automation-mode browser_with_helper --timeout-ms 30000 --output-format json"
40969
41185
  ],
40970
41186
  "notes": [],
40971
41187
  "groupId": "session_lifecycle",
@@ -41009,7 +41225,7 @@ var PUBLIC_SURFACE_MANIFEST = {
41009
41225
  {
41010
41226
  "name": "research",
41011
41227
  "description": "Run research workflows",
41012
- "usage": "npx opendevbrowser research run --topic <text> [--days <n>|--from <date> --to <date>] [--source-selection <family>] [--sources <csv>] [--include-engagement] [--limit-per-source <n>] [--mode <mode>] [--timeout-ms <ms>] [--output-dir <path>] [--ttl-hours <n>] [--use-cookies[=<bool>]] [--challenge-automation-mode <mode>] [--cookie-policy-override <policy>]",
41228
+ "usage": "npx opendevbrowser research run --topic <text> [--days <n>|--from <date> --to <date>] [--source-selection <family>] [--sources <csv>] [--include-engagement] [--limit-per-source <n>] [--browser-mode <mode>] [--mode <mode>] [--timeout-ms <ms>] [--output-dir <path>] [--ttl-hours <n>] [--use-cookies[=<bool>]] [--challenge-automation-mode <mode>] [--cookie-policy-override <policy>]",
41013
41229
  "flags": [
41014
41230
  "--topic",
41015
41231
  "--days",
@@ -41019,6 +41235,7 @@ var PUBLIC_SURFACE_MANIFEST = {
41019
41235
  "--sources",
41020
41236
  "--include-engagement",
41021
41237
  "--limit-per-source",
41238
+ "--browser-mode",
41022
41239
  "--mode",
41023
41240
  "--timeout-ms",
41024
41241
  "--output-dir",
@@ -41029,7 +41246,7 @@ var PUBLIC_SURFACE_MANIFEST = {
41029
41246
  "--cookie-policy"
41030
41247
  ],
41031
41248
  "examples": [
41032
- 'npx opendevbrowser research run --topic "Chrome extension debugging workflows" --days 30 --source-selection auto --mode json --output-format json'
41249
+ 'npx opendevbrowser research run --topic "Chrome extension debugging workflows" --days 30 --source-selection auto --browser-mode managed --mode json --output-format json'
41033
41250
  ],
41034
41251
  "notes": [
41035
41252
  "Generic topical research is currently safest with --source-selection auto; add shopping only for deliberate commercial comparison."
@@ -41059,7 +41276,7 @@ var PUBLIC_SURFACE_MANIFEST = {
41059
41276
  "--cookie-policy"
41060
41277
  ],
41061
41278
  "examples": [
41062
- 'npx opendevbrowser shopping run --query "wireless ergonomic mouse" --providers shopping/bestbuy,shopping/ebay --budget 150 --browser-mode managed --mode json --output-format json'
41279
+ 'npx opendevbrowser shopping run --query "wireless ergonomic mouse" --providers shopping/bestbuy,shopping/ebay --budget 150 --browser-mode managed --use-cookies --challenge-automation-mode browser_with_helper --mode json --output-format json'
41063
41280
  ],
41064
41281
  "notes": [
41065
41282
  "Treat --region as advisory unless the workflow output reports region_authoritative=true."
@@ -41071,7 +41288,7 @@ var PUBLIC_SURFACE_MANIFEST = {
41071
41288
  {
41072
41289
  "name": "product-video",
41073
41290
  "description": "Run product presentation asset workflows",
41074
- "usage": "npx opendevbrowser product-video run (--product-url <url> | --product-name <name>) [--provider-hint <provider>] [--include-screenshots <bool>] [--include-all-images <bool>] [--include-copy <bool>] [--timeout-ms <ms>] [--use-cookies[=<bool>]] [--challenge-automation-mode <mode>] [--cookie-policy-override <policy>] [--output-dir <path>] [--ttl-hours <n>]",
41291
+ "usage": "npx opendevbrowser product-video run (--product-url <url> | --product-name <name>) [--provider-hint <provider>] [--include-screenshots[=<bool>]] [--include-all-images[=<bool>]] [--include-copy[=<bool>]] [--timeout-ms <ms>] [--browser-mode <mode>] [--use-cookies[=<bool>]] [--challenge-automation-mode <mode>] [--cookie-policy-override <policy>] [--output-dir <path>] [--ttl-hours <n>]",
41075
41292
  "flags": [
41076
41293
  "--product-url",
41077
41294
  "--product-name",
@@ -41080,6 +41297,7 @@ var PUBLIC_SURFACE_MANIFEST = {
41080
41297
  "--include-all-images",
41081
41298
  "--include-copy",
41082
41299
  "--timeout-ms",
41300
+ "--browser-mode",
41083
41301
  "--use-cookies",
41084
41302
  "--challenge-automation-mode",
41085
41303
  "--cookie-policy-override",
@@ -41088,7 +41306,7 @@ var PUBLIC_SURFACE_MANIFEST = {
41088
41306
  "--ttl-hours"
41089
41307
  ],
41090
41308
  "examples": [
41091
- 'npx opendevbrowser product-video run --product-url "https://example.com/p/1" --include-screenshots --output-format json'
41309
+ 'npx opendevbrowser product-video run --product-url "https://example.com/p/1" --browser-mode managed --use-cookies --challenge-automation-mode browser_with_helper --include-screenshots --output-format json'
41092
41310
  ],
41093
41311
  "notes": [
41094
41312
  "Confirm whether the returned pack is visual-ready or metadata-first before briefing production."
@@ -41100,7 +41318,7 @@ var PUBLIC_SURFACE_MANIFEST = {
41100
41318
  {
41101
41319
  "name": "inspiredesign",
41102
41320
  "description": "Run inspiredesign workflows",
41103
- "usage": "npx opendevbrowser inspiredesign run --brief <text> [--url <url>]... [--capture-mode <mode>] [--include-prototype-guidance[=<bool>]] [--mode <mode>] [--timeout-ms <ms>] [--output-dir <path>] [--ttl-hours <n>] [--use-cookies[=<bool>]] [--challenge-automation-mode <mode>] [--cookie-policy-override <policy>]",
41321
+ "usage": "npx opendevbrowser inspiredesign run --brief <text> [--url <url>]... [--capture-mode <mode>] [--include-prototype-guidance[=<bool>]] [--mode <mode>] [--timeout-ms <ms>] [--output-dir <path>] [--ttl-hours <n>] [--browser-mode <mode>] [--use-cookies[=<bool>]] [--challenge-automation-mode <mode>] [--cookie-policy-override <policy>]",
41104
41322
  "flags": [
41105
41323
  "--brief",
41106
41324
  "--url",
@@ -41110,13 +41328,14 @@ var PUBLIC_SURFACE_MANIFEST = {
41110
41328
  "--timeout-ms",
41111
41329
  "--output-dir",
41112
41330
  "--ttl-hours",
41331
+ "--browser-mode",
41113
41332
  "--use-cookies",
41114
41333
  "--challenge-automation-mode",
41115
41334
  "--cookie-policy-override",
41116
41335
  "--cookie-policy"
41117
41336
  ],
41118
41337
  "examples": [
41119
- 'npx opendevbrowser inspiredesign run --brief "Extract a reusable dashboard design contract from live references" --url https://linear.app --include-prototype-guidance --output-dir /tmp/inspiredesign --output-format json'
41338
+ 'npx opendevbrowser inspiredesign run --brief "Extract a reusable dashboard design contract from live references" --url https://linear.app --browser-mode managed --use-cookies --challenge-automation-mode browser_with_helper --include-prototype-guidance --output-dir /tmp/inspiredesign --output-format json'
41120
41339
  ],
41121
41340
  "notes": [
41122
41341
  "Any inspiredesign --url forces deep capture for DOM/layout evidence; without URLs, --capture-mode defaults to off.",
@@ -41145,19 +41364,21 @@ var PUBLIC_SURFACE_MANIFEST = {
41145
41364
  {
41146
41365
  "name": "macro-resolve",
41147
41366
  "description": "Resolve or execute a macro expression via provider actions",
41148
- "usage": "npx opendevbrowser macro-resolve --expression <macro> [--default-provider <provider>] [--include-catalog] [--execute] [--timeout-ms <ms>] [--challenge-automation-mode <mode>]",
41367
+ "usage": "npx opendevbrowser macro-resolve --expression <macro> [--default-provider <provider>] [--include-catalog] [--execute [--timeout-ms <ms>] [--browser-mode <mode>] [--challenge-automation-mode <mode>]]",
41149
41368
  "flags": [
41150
41369
  "--expression",
41151
41370
  "--default-provider",
41152
41371
  "--include-catalog",
41153
41372
  "--execute",
41154
41373
  "--timeout-ms",
41374
+ "--browser-mode",
41155
41375
  "--challenge-automation-mode"
41156
41376
  ],
41157
41377
  "examples": [
41158
- `npx opendevbrowser macro-resolve --expression '@community.search("browser automation failures", 4)' --execute --challenge-automation-mode browser --output-format json`
41378
+ `npx opendevbrowser macro-resolve --expression '@community.search("browser automation failures", 4)' --execute --browser-mode extension --challenge-automation-mode browser_with_helper --output-format json`
41159
41379
  ],
41160
41380
  "notes": [
41381
+ "Use --browser-mode and --challenge-automation-mode only with --execute.",
41161
41382
  "When --execute is enabled, inspect execution.meta.blocker before trusting a blocked result as complete."
41162
41383
  ],
41163
41384
  "groupId": "provider_workflows",
@@ -41823,7 +42044,7 @@ var PUBLIC_SURFACE_MANIFEST = {
41823
42044
  "--timeout-ms"
41824
42045
  ],
41825
42046
  "examples": [
41826
- "npx opendevbrowser session-inspector-plan --session-id s1 --target-id page-1 --challenge-automation-mode browser --output-format json"
42047
+ "npx opendevbrowser session-inspector-plan --session-id s1 --target-id page-1 --challenge-automation-mode browser_with_helper --output-format json"
41827
42048
  ],
41828
42049
  "notes": [
41829
42050
  "Inspect browser-scoped challenge automation before enabling browser_with_helper on a live rerun."
@@ -42317,7 +42538,7 @@ var PUBLIC_SURFACE_MANIFEST = {
42317
42538
  },
42318
42539
  {
42319
42540
  "name": "--dy",
42320
- "kind": "boolean"
42541
+ "kind": "value"
42321
42542
  },
42322
42543
  {
42323
42544
  "name": "--key",
@@ -42673,6 +42894,7 @@ var PUBLIC_SURFACE_MANIFEST = {
42673
42894
  "--since-network-seq",
42674
42895
  "--since-exception-seq",
42675
42896
  "--max",
42897
+ "--dy",
42676
42898
  "--target-id",
42677
42899
  "--window-id",
42678
42900
  "--tab-id",
@@ -42768,7 +42990,7 @@ var PUBLIC_SURFACE_MANIFEST = {
42768
42990
  "name": "opendevbrowser_status_capabilities",
42769
42991
  "description": "Inspect runtime capability discovery for the host and an optional session.",
42770
42992
  "cliEquivalent": "status-capabilities",
42771
- "example": "npx opendevbrowser status-capabilities --session-id s1 --target-id page-1 --challenge-automation-mode browser --timeout-ms 30000 --output-format json"
42993
+ "example": "npx opendevbrowser status-capabilities --session-id s1 --target-id page-1 --challenge-automation-mode browser_with_helper --timeout-ms 30000 --output-format json"
42772
42994
  },
42773
42995
  {
42774
42996
  "name": "opendevbrowser_session_inspector",
@@ -42780,7 +43002,7 @@ var PUBLIC_SURFACE_MANIFEST = {
42780
43002
  "name": "opendevbrowser_session_inspector_plan",
42781
43003
  "description": "Inspect browser-scoped computer-use policy, eligibility, and safe suggested steps.",
42782
43004
  "cliEquivalent": "session-inspector-plan",
42783
- "example": "npx opendevbrowser session-inspector-plan --session-id s1 --target-id page-1 --challenge-automation-mode browser --output-format json"
43005
+ "example": "npx opendevbrowser session-inspector-plan --session-id s1 --target-id page-1 --challenge-automation-mode browser_with_helper --output-format json"
42784
43006
  },
42785
43007
  {
42786
43008
  "name": "opendevbrowser_session_inspector_audit",
@@ -43034,31 +43256,31 @@ var PUBLIC_SURFACE_MANIFEST = {
43034
43256
  "name": "opendevbrowser_macro_resolve",
43035
43257
  "description": "Resolve or execute provider macro expressions.",
43036
43258
  "cliEquivalent": "macro-resolve",
43037
- "example": `npx opendevbrowser macro-resolve --expression '@community.search("browser automation failures", 4)' --execute --challenge-automation-mode browser --output-format json`
43259
+ "example": `npx opendevbrowser macro-resolve --expression '@community.search("browser automation failures", 4)' --execute --browser-mode extension --challenge-automation-mode browser_with_helper --output-format json`
43038
43260
  },
43039
43261
  {
43040
43262
  "name": "opendevbrowser_research_run",
43041
43263
  "description": "Run the research workflow directly.",
43042
43264
  "cliEquivalent": "research",
43043
- "example": 'npx opendevbrowser research run --topic "Chrome extension debugging workflows" --days 30 --source-selection auto --mode json --output-format json'
43265
+ "example": 'npx opendevbrowser research run --topic "Chrome extension debugging workflows" --days 30 --source-selection auto --browser-mode managed --mode json --output-format json'
43044
43266
  },
43045
43267
  {
43046
43268
  "name": "opendevbrowser_shopping_run",
43047
43269
  "description": "Run the shopping workflow directly.",
43048
43270
  "cliEquivalent": "shopping",
43049
- "example": 'npx opendevbrowser shopping run --query "wireless ergonomic mouse" --providers shopping/bestbuy,shopping/ebay --budget 150 --browser-mode managed --mode json --output-format json'
43271
+ "example": 'npx opendevbrowser shopping run --query "wireless ergonomic mouse" --providers shopping/bestbuy,shopping/ebay --budget 150 --browser-mode managed --use-cookies --challenge-automation-mode browser_with_helper --mode json --output-format json'
43050
43272
  },
43051
43273
  {
43052
43274
  "name": "opendevbrowser_product_video_run",
43053
43275
  "description": "Run the product-video asset workflow directly.",
43054
43276
  "cliEquivalent": "product-video",
43055
- "example": 'npx opendevbrowser product-video run --product-url "https://example.com/p/1" --include-screenshots --output-format json'
43277
+ "example": 'npx opendevbrowser product-video run --product-url "https://example.com/p/1" --browser-mode managed --use-cookies --challenge-automation-mode browser_with_helper --include-screenshots --output-format json'
43056
43278
  },
43057
43279
  {
43058
43280
  "name": "opendevbrowser_inspiredesign_run",
43059
43281
  "description": "Run the inspiredesign workflow directly.",
43060
43282
  "cliEquivalent": "inspiredesign",
43061
- "example": 'npx opendevbrowser inspiredesign run --brief "Extract a reusable dashboard design contract from live references" --url https://linear.app --include-prototype-guidance --output-dir /tmp/inspiredesign --output-format json'
43283
+ "example": 'npx opendevbrowser inspiredesign run --brief "Extract a reusable dashboard design contract from live references" --url https://linear.app --browser-mode managed --use-cookies --challenge-automation-mode browser_with_helper --include-prototype-guidance --output-dir /tmp/inspiredesign --output-format json'
43062
43284
  },
43063
43285
  {
43064
43286
  "name": "opendevbrowser_canvas",
@@ -43544,4 +43766,4 @@ export {
43544
43766
  TOOL_SURFACE_ENTRIES
43545
43767
  };
43546
43768
  /* v8 ignore next -- @preserve */
43547
- //# sourceMappingURL=chunk-GTTYIAI7.js.map
43769
+ //# sourceMappingURL=chunk-I5ZCOZZV.js.map