opendevbrowser 0.0.19 → 0.0.21

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 (173) hide show
  1. package/README.md +32 -24
  2. package/dist/automation/coordinator.d.ts +61 -2
  3. package/dist/automation/coordinator.d.ts.map +1 -1
  4. package/dist/browser/browser-manager.d.ts +6 -1
  5. package/dist/browser/browser-manager.d.ts.map +1 -1
  6. package/dist/browser/canvas-manager.d.ts +4 -0
  7. package/dist/browser/canvas-manager.d.ts.map +1 -1
  8. package/dist/browser/manager-types.d.ts +6 -1
  9. package/dist/browser/manager-types.d.ts.map +1 -1
  10. package/dist/browser/ops-browser-manager.d.ts +6 -1
  11. package/dist/browser/ops-browser-manager.d.ts.map +1 -1
  12. package/dist/browser/screencast-recorder.d.ts.map +1 -1
  13. package/dist/browser/session-inspector.d.ts +39 -0
  14. package/dist/browser/session-inspector.d.ts.map +1 -1
  15. package/dist/canvas/document-store.d.ts +14 -5
  16. package/dist/canvas/document-store.d.ts.map +1 -1
  17. package/dist/canvas/starters/catalog.d.ts.map +1 -1
  18. package/dist/canvas/types.d.ts +120 -9
  19. package/dist/canvas/types.d.ts.map +1 -1
  20. package/dist/challenges/action-loop.d.ts +2 -1
  21. package/dist/challenges/action-loop.d.ts.map +1 -1
  22. package/dist/challenges/capture.d.ts +14 -0
  23. package/dist/challenges/capture.d.ts.map +1 -0
  24. package/dist/challenges/index.d.ts +3 -1
  25. package/dist/challenges/index.d.ts.map +1 -1
  26. package/dist/challenges/inspect-plan.d.ts +40 -0
  27. package/dist/challenges/inspect-plan.d.ts.map +1 -0
  28. package/dist/challenges/orchestrator.d.ts.map +1 -1
  29. package/dist/challenges/types.d.ts +34 -0
  30. package/dist/challenges/types.d.ts.map +1 -1
  31. package/dist/{chunk-YBQECXZX.js → chunk-3VA6XR25.js} +3 -3
  32. package/dist/chunk-3VA6XR25.js.map +1 -0
  33. package/dist/{chunk-W4IHGDXV.js → chunk-4KVXCXV3.js} +25778 -24279
  34. package/dist/chunk-4KVXCXV3.js.map +1 -0
  35. package/dist/{chunk-5FZQJRBQ.js → chunk-ZE2E7ZGH.js} +3013 -1010
  36. package/dist/chunk-ZE2E7ZGH.js.map +1 -0
  37. package/dist/cli/commands/challenge-automation-mode.d.ts +3 -0
  38. package/dist/cli/commands/challenge-automation-mode.d.ts.map +1 -0
  39. package/dist/cli/commands/inspiredesign.d.ts +25 -0
  40. package/dist/cli/commands/inspiredesign.d.ts.map +1 -0
  41. package/dist/cli/commands/macro-resolve.d.ts.map +1 -1
  42. package/dist/cli/commands/nav/review-desktop.d.ts +7 -0
  43. package/dist/cli/commands/nav/review-desktop.d.ts.map +1 -0
  44. package/dist/cli/commands/nav/review-shared.d.ts +10 -0
  45. package/dist/cli/commands/nav/review-shared.d.ts.map +1 -0
  46. package/dist/cli/commands/nav/review.d.ts.map +1 -1
  47. package/dist/cli/commands/serve.d.ts.map +1 -1
  48. package/dist/cli/commands/session/inspector-audit.d.ts +7 -0
  49. package/dist/cli/commands/session/inspector-audit.d.ts.map +1 -0
  50. package/dist/cli/commands/session/inspector-plan.d.ts +7 -0
  51. package/dist/cli/commands/session/inspector-plan.d.ts.map +1 -0
  52. package/dist/cli/commands/session/inspector-shared.d.ts +11 -0
  53. package/dist/cli/commands/session/inspector-shared.d.ts.map +1 -0
  54. package/dist/cli/commands/session/inspector.d.ts +1 -11
  55. package/dist/cli/commands/session/inspector.d.ts.map +1 -1
  56. package/dist/cli/commands/status-capabilities.d.ts +7 -0
  57. package/dist/cli/commands/status-capabilities.d.ts.map +1 -0
  58. package/dist/cli/daemon-client.d.ts.map +1 -1
  59. package/dist/cli/daemon-commands.d.ts.map +1 -1
  60. package/dist/cli/daemon-status.d.ts +5 -0
  61. package/dist/cli/daemon-status.d.ts.map +1 -1
  62. package/dist/cli/daemon.d.ts +5 -0
  63. package/dist/cli/daemon.d.ts.map +1 -1
  64. package/dist/cli/help.d.ts +2 -0
  65. package/dist/cli/help.d.ts.map +1 -1
  66. package/dist/cli/index.js +660 -244
  67. package/dist/cli/index.js.map +1 -1
  68. package/dist/cli/remote-manager.d.ts +6 -0
  69. package/dist/cli/remote-manager.d.ts.map +1 -1
  70. package/dist/cli/utils/parse.d.ts +1 -0
  71. package/dist/cli/utils/parse.d.ts.map +1 -1
  72. package/dist/cli/utils/skills.d.ts +1 -1
  73. package/dist/cli/utils/skills.d.ts.map +1 -1
  74. package/dist/cli/utils/workflow-message.d.ts +3 -0
  75. package/dist/cli/utils/workflow-message.d.ts.map +1 -1
  76. package/dist/config.d.ts +1 -0
  77. package/dist/config.d.ts.map +1 -1
  78. package/dist/core/bootstrap.d.ts.map +1 -1
  79. package/dist/core/runtime-assemblies.d.ts +2 -1
  80. package/dist/core/runtime-assemblies.d.ts.map +1 -1
  81. package/dist/core/types.d.ts +1 -1
  82. package/dist/core/types.d.ts.map +1 -1
  83. package/dist/desktop/runtime.d.ts +1 -0
  84. package/dist/desktop/runtime.d.ts.map +1 -1
  85. package/dist/index.d.ts.map +1 -1
  86. package/dist/index.js +729 -448
  87. package/dist/index.js.map +1 -1
  88. package/dist/inspiredesign/handoff.d.ts +34 -0
  89. package/dist/inspiredesign/handoff.d.ts.map +1 -0
  90. package/dist/opendevbrowser.d.ts.map +1 -1
  91. package/dist/opendevbrowser.js +729 -448
  92. package/dist/opendevbrowser.js.map +1 -1
  93. package/dist/providers/browser-fallback.d.ts.map +1 -1
  94. package/dist/providers/constraint.d.ts +11 -0
  95. package/dist/providers/constraint.d.ts.map +1 -1
  96. package/dist/providers/cookie-source.d.ts +8 -0
  97. package/dist/providers/cookie-source.d.ts.map +1 -0
  98. package/dist/providers/index.d.ts.map +1 -1
  99. package/dist/providers/inspiredesign-capture.d.ts +17 -0
  100. package/dist/providers/inspiredesign-capture.d.ts.map +1 -0
  101. package/dist/providers/inspiredesign-contract.d.ts +110 -0
  102. package/dist/providers/inspiredesign-contract.d.ts.map +1 -0
  103. package/dist/providers/renderer.d.ts +23 -0
  104. package/dist/providers/renderer.d.ts.map +1 -1
  105. package/dist/providers/runtime-bundle.d.ts +2 -1
  106. package/dist/providers/runtime-bundle.d.ts.map +1 -1
  107. package/dist/providers/runtime-factory.d.ts +4 -2
  108. package/dist/providers/runtime-factory.d.ts.map +1 -1
  109. package/dist/providers/shopping/index.d.ts +1 -1
  110. package/dist/providers/types.d.ts +3 -2
  111. package/dist/providers/types.d.ts.map +1 -1
  112. package/dist/providers/workflow-contracts.d.ts +1 -1
  113. package/dist/providers/workflow-contracts.d.ts.map +1 -1
  114. package/dist/providers/workflow-handoff.d.ts +14 -0
  115. package/dist/providers/workflow-handoff.d.ts.map +1 -0
  116. package/dist/providers/workflows.d.ts +21 -2
  117. package/dist/providers/workflows.d.ts.map +1 -1
  118. package/dist/{providers-G36AM3Z2.js → providers-ZIVHHH4F.js} +6 -2
  119. package/dist/public-surface/generated-manifest.d.ts +143 -7
  120. package/dist/public-surface/generated-manifest.d.ts.map +1 -1
  121. package/dist/public-surface/source.d.ts +102 -3
  122. package/dist/public-surface/source.d.ts.map +1 -1
  123. package/dist/relay/protocol.d.ts +1 -1
  124. package/dist/relay/protocol.d.ts.map +1 -1
  125. package/dist/relay/relay-server.d.ts +1 -0
  126. package/dist/relay/relay-server.d.ts.map +1 -1
  127. package/dist/skills/skill-loader.js +1 -1
  128. package/dist/tools/automation-shared.d.ts +6 -0
  129. package/dist/tools/automation-shared.d.ts.map +1 -0
  130. package/dist/tools/index.d.ts.map +1 -1
  131. package/dist/tools/inspiredesign_run.d.ts +4 -0
  132. package/dist/tools/inspiredesign_run.d.ts.map +1 -0
  133. package/dist/tools/review_desktop.d.ts +4 -0
  134. package/dist/tools/review_desktop.d.ts.map +1 -0
  135. package/dist/tools/session_inspector.d.ts.map +1 -1
  136. package/dist/tools/session_inspector_audit.d.ts +4 -0
  137. package/dist/tools/session_inspector_audit.d.ts.map +1 -0
  138. package/dist/tools/session_inspector_plan.d.ts +4 -0
  139. package/dist/tools/session_inspector_plan.d.ts.map +1 -0
  140. package/dist/tools/status_capabilities.d.ts +4 -0
  141. package/dist/tools/status_capabilities.d.ts.map +1 -0
  142. package/extension/dist/background.js +70 -10
  143. package/extension/dist/canvas/canvas-runtime.js +14 -1
  144. package/extension/dist/ops/ops-runtime.js +18 -1
  145. package/extension/dist/popup.js +29 -16
  146. package/extension/dist/services/ConnectionManager.js +27 -2
  147. package/extension/manifest.json +1 -1
  148. package/extension/popup.html +11 -0
  149. package/package.json +5 -5
  150. package/skills/AGENTS.md +2 -2
  151. package/skills/opendevbrowser-best-practices/SKILL.md +50 -15
  152. package/skills/opendevbrowser-best-practices/artifacts/canvas-governance-playbook.md +31 -12
  153. package/skills/opendevbrowser-best-practices/artifacts/command-channel-reference.md +64 -15
  154. package/skills/opendevbrowser-best-practices/artifacts/provider-workflows.md +4 -0
  155. package/skills/opendevbrowser-best-practices/artifacts/skill-runtime-surface-matrix.md +11 -10
  156. package/skills/opendevbrowser-best-practices/assets/templates/canvas-blocker-checklist.json +28 -22
  157. package/skills/opendevbrowser-best-practices/assets/templates/canvas-generation-plan.v1.json +18 -17
  158. package/skills/opendevbrowser-best-practices/assets/templates/canvas-handshake-example.json +135 -17
  159. package/skills/opendevbrowser-best-practices/assets/templates/skill-runtime-pack-matrix.json +55 -8
  160. package/skills/opendevbrowser-best-practices/assets/templates/surface-audit-checklist.json +18 -4
  161. package/skills/opendevbrowser-best-practices/scripts/odb-workflow.sh +16 -4
  162. package/skills/opendevbrowser-best-practices/scripts/run-robustness-audit.sh +3 -1
  163. package/skills/opendevbrowser-best-practices/scripts/validate-skill-assets.sh +68 -25
  164. package/skills/opendevbrowser-design-agent/SKILL.md +9 -4
  165. package/skills/opendevbrowser-design-agent/artifacts/design-workflows.md +15 -6
  166. package/skills/opendevbrowser-design-agent/assets/templates/canvas-generation-plan.design.v1.json +18 -17
  167. package/skills/opendevbrowser-design-agent/scripts/design-workflow.sh +11 -0
  168. package/skills/opendevbrowser-design-agent/scripts/validate-skill-assets.sh +57 -0
  169. package/skills/opendevbrowser-product-presentation-asset/SKILL.md +2 -2
  170. package/dist/chunk-5FZQJRBQ.js.map +0 -1
  171. package/dist/chunk-W4IHGDXV.js.map +0 -1
  172. package/dist/chunk-YBQECXZX.js.map +0 -1
  173. /package/dist/{providers-G36AM3Z2.js.map → providers-ZIVHHH4F.js.map} +0 -0
package/dist/cli/index.js CHANGED
@@ -21,6 +21,7 @@ import {
21
21
  formatErrorPayload,
22
22
  generateSecureToken,
23
23
  getChromeUserDataRoots,
24
+ getCurrentDaemonFingerprint,
24
25
  getExtensionPath,
25
26
  getProfileDirs,
26
27
  loadGlobalConfig,
@@ -30,22 +31,24 @@ import {
30
31
  resolveExitCode,
31
32
  startDaemon,
32
33
  toCliError
33
- } from "../chunk-W4IHGDXV.js";
34
+ } from "../chunk-4KVXCXV3.js";
34
35
  import {
35
36
  getBundledSkillsDir,
36
37
  listBundledSkillDirectories
37
- } from "../chunk-YBQECXZX.js";
38
- import "../chunk-Y2KL55OG.js";
38
+ } from "../chunk-3VA6XR25.js";
39
39
  import {
40
40
  writeFileAtomic
41
41
  } from "../chunk-TBUCZX4A.js";
42
+ import "../chunk-Y2KL55OG.js";
42
43
  import {
44
+ INSPIREDESIGN_HANDOFF_COMMANDS,
45
+ INSPIREDESIGN_HANDOFF_GUIDANCE,
43
46
  cleanupExpiredArtifacts,
44
47
  isChallengeAutomationMode,
45
48
  setDefaultLogSink,
46
49
  stderrSink,
47
50
  summarizePrimaryProviderIssue
48
- } from "../chunk-5FZQJRBQ.js";
51
+ } from "../chunk-ZE2E7ZGH.js";
49
52
  import "../chunk-FUSXMW3G.js";
50
53
 
51
54
  // src/cli/args.ts
@@ -245,25 +248,18 @@ function detectOutputFormat(argv) {
245
248
  }
246
249
  }
247
250
 
248
- // src/cli/commands/registry.ts
249
- var registry = /* @__PURE__ */ new Map();
250
- function registerCommand(definition) {
251
- registry.set(definition.name, definition);
252
- }
253
- function getCommand(name) {
254
- return registry.get(name);
255
- }
256
- function listCommands() {
257
- return Array.from(registry.values());
258
- }
259
-
260
251
  // src/cli/help.ts
261
252
  var LABEL_WIDTH = 42;
262
253
  var DETAIL_LABEL_WIDTH = 9;
263
254
  var COMMAND_SET = new Set(CLI_COMMANDS);
264
255
  var FLAG_SET = new Set(VALID_FLAGS);
265
256
  var TOOL_COUNT = TOOL_SURFACE_ENTRIES.length;
257
+ var CLI_EQUIVALENT_SET = new Set(
258
+ TOOL_SURFACE_ENTRIES.flatMap((entry) => entry.cliEquivalent ? [entry.cliEquivalent] : [])
259
+ );
266
260
  var formatFlags = (flags) => flags.length > 0 ? flags.join(", ") : "none";
261
+ var getCliOnlyCommands = () => CLI_COMMANDS.filter((command) => !CLI_EQUIVALENT_SET.has(command));
262
+ var getToolOnlyHelperNames = () => TOOL_SURFACE_ENTRIES.filter((entry) => !entry.cliEquivalent).map((entry) => entry.name);
267
263
  var HELP_COMMAND_GROUPS = PUBLIC_CLI_COMMAND_GROUPS.map((group) => ({
268
264
  title: group.title,
269
265
  summary: group.summary,
@@ -330,7 +326,7 @@ var HELP_FLAG_GROUPS = [
330
326
  title: "Navigation / Interaction / Diagnostics Flags",
331
327
  summary: "Command-specific flags for page actions, reads, and diagnostics.",
332
328
  flags: [
333
- { flag: "--url", description: "Target URL for navigation, connect, or workflow commands.", example: "opendevbrowser goto --session-id s1 --url https://example.com" },
329
+ { flag: "--url", description: "Target URL for navigation, connect, or workflow commands; repeat for multi-reference inspiredesign runs.", example: "opendevbrowser goto --session-id s1 --url https://example.com" },
334
330
  { flag: "--wait-until", description: "Navigation wait strategy such as load or domcontentloaded." },
335
331
  { flag: "--timeout-ms", description: "Operation timeout in milliseconds.", example: "opendevbrowser canvas --timeout-ms 120000 --command canvas.session.open ..." },
336
332
  { flag: "--ref", description: "Snapshot ref id for element-targeted commands.", example: "opendevbrowser click --session-id s1 --ref r12" },
@@ -409,6 +405,9 @@ var HELP_FLAG_GROUPS = [
409
405
  { flag: "--budget", description: "Budget filter for shopping workflows." },
410
406
  { flag: "--region", description: "Region or country hint for provider selection. Treat it as advisory unless output metadata reports `region_authoritative=true`." },
411
407
  { flag: "--sort", description: "Sort mode for shopping results." },
408
+ { flag: "--brief", description: "Inspiredesign brief describing the target design direction." },
409
+ { flag: "--capture-mode", description: "Inspiredesign capture mode: off (default) or deep." },
410
+ { flag: "--include-prototype-guidance", description: "Include inspiredesign prototype guidance in workflow output." },
412
411
  { flag: "--product-url", description: "Target product URL for product-video workflows." },
413
412
  { flag: "--product-name", description: "Product name override for product-video workflows." },
414
413
  { flag: "--provider-hint", description: "Provider hint override for product workflows." },
@@ -438,7 +437,7 @@ var HELP_CAPABILITY_ENTRIES = [
438
437
  },
439
438
  {
440
439
  label: "desktop observation",
441
- description: "Use the public read-only desktop observation plane for sibling desktop evidence on macOS; window inventory and accessibility probes use the local swift command, while screenshots use screencapture outside extension relay.",
440
+ description: "Use the public read-only desktop observation plane for sibling desktop evidence on macOS; availability, window inventory, and accessibility probes use the local swift command, while screenshots use macOS screencapture outside extension relay.",
442
441
  details: [
443
442
  {
444
443
  label: "cli:",
@@ -452,7 +451,7 @@ var HELP_CAPABILITY_ENTRIES = [
452
451
  description: "Control the bounded browser-scoped computer-use challenge lane with --challenge-automation-mode; the optional helper is not a desktop agent.",
453
452
  details: [
454
453
  { label: "flag:", value: "--challenge-automation-mode off|browser|browser_with_helper" },
455
- { label: "works:", value: "research run, shopping run, product-video run, macro-resolve --execute" },
454
+ { label: "works:", value: "research run, shopping run, product-video run, inspiredesign run, macro-resolve --execute" },
456
455
  { label: "entry:", value: onboarding_metadata_default.quickStartCommands.computerUseEntry },
457
456
  { label: "proof:", value: "review, session-inspector, workflow fallback metadata" }
458
457
  ]
@@ -489,6 +488,16 @@ var HELP_ONBOARDING_ENTRIES = [
489
488
  description: "Start deal hunting with explicit providers in managed mode and only trust regional comparisons when the result reports `region_authoritative=true`.",
490
489
  details: [{ label: "cli:", value: onboarding_metadata_default.quickStartCommands.validatedShopping }]
491
490
  },
491
+ {
492
+ label: "inspiredesign_followthrough",
493
+ description: "After inspiredesign finishes, continue in Canvas with the emitted request template and load the canvas-contract design-agent lane before patching.",
494
+ details: [
495
+ { label: "quick:", value: INSPIREDESIGN_HANDOFF_COMMANDS.loadBestPractices },
496
+ { label: "design:", value: INSPIREDESIGN_HANDOFF_COMMANDS.loadDesignAgent },
497
+ { label: "prep:", value: INSPIREDESIGN_HANDOFF_GUIDANCE.prepareCanvasPlanRequest },
498
+ { label: "run:", value: INSPIREDESIGN_HANDOFF_COMMANDS.continueInCanvas }
499
+ ]
500
+ },
492
501
  {
493
502
  label: "computer_use_entry",
494
503
  description: "Enter browser-scoped computer use from a workflow run, not from a separate desktop command family.",
@@ -499,6 +508,14 @@ var HELP_ONBOARDING_ENTRIES = [
499
508
  description: "After guidance, verify a minimal managed happy path before widening into multi-step automation.",
500
509
  details: [{ label: "cli:", value: onboarding_metadata_default.quickStartCommands.happyPath }]
501
510
  },
511
+ {
512
+ label: "surface_split",
513
+ description: "Use the existing public-surface split when a workflow or helper only exists on one side of the CLI or tool surface.",
514
+ details: [
515
+ { label: "cli-only:", value: getCliOnlyCommands().join(", ") },
516
+ { label: "tool-only:", value: getToolOnlyHelperNames().join(", ") }
517
+ ]
518
+ },
502
519
  {
503
520
  label: "docs",
504
521
  description: "Use the first-run checklist and canonical skill runbook for proof and deeper operating details.",
@@ -510,6 +527,7 @@ var HELP_ONBOARDING_ENTRIES = [
510
527
  ];
511
528
  var HELP_REFERENCE_ENTRIES = [
512
529
  { label: "src/cli/onboarding-metadata.json", description: "Canonical first-contact onboarding metadata shared by help, nudges, and proof lanes." },
530
+ { label: "src/inspiredesign/handoff.ts", description: "Shared inspiredesign follow-through commands, artifact names, and Canvas continuation guidance." },
513
531
  { label: "src/public-surface/source.ts", description: "Authoritative command, usage, flag, and tool surface metadata." },
514
532
  { label: "src/public-surface/generated-manifest.ts", description: "Checked-in generated public-surface snapshot consumed by help and parity tests." },
515
533
  { label: "src/public-surface/generated-manifest.json", description: "Checked-in generated public-surface snapshot consumed by inventory scripts." },
@@ -519,6 +537,7 @@ var HELP_REFERENCE_ENTRIES = [
519
537
  { label: "docs/CLI.md", description: "Detailed CLI guide and release-gate runbooks." },
520
538
  { label: onboarding_metadata_default.referencePaths.onboardingDoc, description: "First-run checklist for help-led onboarding and happy-path proof." },
521
539
  { label: onboarding_metadata_default.referencePaths.skillDoc, description: "Canonical bundled best-practices runbook and quick-start guidance." },
540
+ { label: "docs/WORKFLOW_SURFACE_MAP.md", description: "Code-derived workflow and validation inventory, including CLI-only and tool-only surface splits." },
522
541
  { label: "docs/SURFACE_REFERENCE.md", description: "Canonical CLI, tool, and relay channel inventory." },
523
542
  { label: "opendevbrowser --help", description: "Primary full help invocation for quick discovery." },
524
543
  { label: "opendevbrowser help", description: "Alias that prints the same full help inventory." }
@@ -532,14 +551,7 @@ function formatRows(rows) {
532
551
  return lines.join("\n");
533
552
  }).join("\n");
534
553
  }
535
- function getCommandDescriptions() {
536
- const descriptions = /* @__PURE__ */ new Map();
537
- for (const definition of listCommands()) {
538
- descriptions.set(definition.name, definition.description);
539
- }
540
- return descriptions;
541
- }
542
- function assertCommandCoverage(commandDescriptions) {
554
+ function assertCommandCoverage() {
543
555
  const seen = /* @__PURE__ */ new Set();
544
556
  for (const group of HELP_COMMAND_GROUPS) {
545
557
  for (const command of group.commands) {
@@ -547,13 +559,10 @@ function assertCommandCoverage(commandDescriptions) {
547
559
  if (!COMMAND_SET.has(command)) {
548
560
  throw new Error(`Help references unknown CLI command: ${command}`);
549
561
  }
550
- if (!commandDescriptions.has(command)) {
551
- throw new Error(`Help references unregistered CLI command: ${command}`);
552
- }
553
562
  if (seen.has(command)) {
554
563
  throw new Error(`Help command appears multiple times: ${command}`);
555
564
  }
556
- if (!detail || !detail.usage.trim()) {
565
+ if (!detail || !detail.description.trim() || !detail.usage.trim()) {
557
566
  throw new Error(`Missing command help metadata: ${command}`);
558
567
  }
559
568
  for (const flag of detail.flags) {
@@ -608,13 +617,13 @@ function assertToolCoverage() {
608
617
  throw new Error(`Help tool inventory must list ${TOOL_COUNT} tools; got ${HELP_TOOL_ENTRIES.length}`);
609
618
  }
610
619
  }
611
- function formatCommandGroups(commandDescriptions) {
620
+ function formatCommandGroups() {
612
621
  return HELP_COMMAND_GROUPS.map((group) => {
613
622
  const rows = group.commands.map((command) => {
614
623
  const detail = COMMAND_HELP_DETAILS[command];
615
624
  return {
616
625
  label: command,
617
- description: commandDescriptions.get(command) ?? "Missing command description.",
626
+ description: detail.description,
618
627
  details: [
619
628
  { label: "usage:", value: detail.usage },
620
629
  { label: "flags:", value: formatFlags(detail.flags) }
@@ -656,8 +665,7 @@ function formatReferenceEntries() {
656
665
  })));
657
666
  }
658
667
  function getHelpText() {
659
- const commandDescriptions = getCommandDescriptions();
660
- assertCommandCoverage(commandDescriptions);
668
+ assertCommandCoverage();
661
669
  assertFlagCoverage();
662
670
  assertToolCoverage();
663
671
  return [
@@ -675,7 +683,7 @@ function getHelpText() {
675
683
  formatOnboardingEntries(),
676
684
  "",
677
685
  `Command Inventory (all ${CLI_COMMANDS.length} commands):`,
678
- formatCommandGroups(commandDescriptions),
686
+ formatCommandGroups(),
679
687
  "",
680
688
  "Flag Inventory (all supported flags):",
681
689
  formatFlagGroups(),
@@ -688,6 +696,15 @@ function getHelpText() {
688
696
  ].join("\n");
689
697
  }
690
698
 
699
+ // src/cli/commands/registry.ts
700
+ var registry = /* @__PURE__ */ new Map();
701
+ function registerCommand(definition) {
702
+ registry.set(definition.name, definition);
703
+ }
704
+ function getCommand(name) {
705
+ return registry.get(name);
706
+ }
707
+
691
708
  // src/cli/installers/global.ts
692
709
  import * as fs3 from "fs";
693
710
 
@@ -964,10 +981,10 @@ function getCodexHomeDir() {
964
981
  return process.env.CODEX_HOME || path3.join(os3.homedir(), ".codex");
965
982
  }
966
983
  function getClaudeCodeHomeDir() {
967
- return process.env.CLAUDECODE_HOME || process.env.CLAUDE_HOME || path3.join(os3.homedir(), ".claude");
984
+ return process.env.CLAUDECODE_HOME || path3.join(os3.homedir(), ".claude");
968
985
  }
969
986
  function getAmpHomeDir() {
970
- return process.env.AMPCLI_HOME || process.env.AMP_CLI_HOME || process.env.AMP_HOME || path3.join(os3.homedir(), ".amp");
987
+ return process.env.AMP_CLI_HOME || path3.join(os3.homedir(), ".amp");
971
988
  }
972
989
  function dedupeTargets(targets) {
973
990
  const deduped = /* @__PURE__ */ new Map();
@@ -991,9 +1008,7 @@ function getGlobalSkillTargets() {
991
1008
  { agent: "opencode", dir: getGlobalSkillDir() },
992
1009
  { agent: "codex", dir: path3.join(getCodexHomeDir(), SKILLS_DIR_NAME) },
993
1010
  { agent: "claudecode", dir: claudeSkillsDir },
994
- { agent: "claude", dir: claudeSkillsDir },
995
- { agent: "ampcli", dir: ampSkillsDir },
996
- { agent: "amp", dir: ampSkillsDir }
1011
+ { agent: "ampcli", dir: ampSkillsDir }
997
1012
  ]);
998
1013
  }
999
1014
  function getLocalSkillTargets() {
@@ -1003,9 +1018,7 @@ function getLocalSkillTargets() {
1003
1018
  { agent: "opencode", dir: getLocalSkillDir() },
1004
1019
  { agent: "codex", dir: path3.join(process.cwd(), ".codex", SKILLS_DIR_NAME) },
1005
1020
  { agent: "claudecode", dir: localClaudeSkillsDir },
1006
- { agent: "claude", dir: localClaudeSkillsDir },
1007
- { agent: "ampcli", dir: localAmpSkillsDir },
1008
- { agent: "amp", dir: localAmpSkillsDir }
1021
+ { agent: "ampcli", dir: localAmpSkillsDir }
1009
1022
  ]);
1010
1023
  }
1011
1024
 
@@ -1511,6 +1524,29 @@ function parseStringArrayFlag(rawArgs, flag) {
1511
1524
  }
1512
1525
  return items;
1513
1526
  }
1527
+ function parseRepeatedStringFlag(rawArgs, flag) {
1528
+ const values = [];
1529
+ for (let index = 0; index < rawArgs.length; index += 1) {
1530
+ const arg = rawArgs[index];
1531
+ if (arg === flag) {
1532
+ const value = rawArgs[index + 1];
1533
+ if (!value) {
1534
+ throw createUsageError(`Missing value for ${flag}`);
1535
+ }
1536
+ values.push(value);
1537
+ index += 1;
1538
+ continue;
1539
+ }
1540
+ if (arg?.startsWith(`${flag}=`)) {
1541
+ const value = arg.split("=", 2)[1];
1542
+ if (!value) {
1543
+ throw createUsageError(`Missing value for ${flag}`);
1544
+ }
1545
+ values.push(value);
1546
+ }
1547
+ }
1548
+ return values.length > 0 ? values : void 0;
1549
+ }
1514
1550
 
1515
1551
  // src/cli/commands/native.ts
1516
1552
  import * as fs8 from "fs";
@@ -1919,6 +1955,32 @@ async function resolveExistingDaemon(port, tokens) {
1919
1955
  }
1920
1956
  return null;
1921
1957
  }
1958
+ function isPositivePid(value) {
1959
+ return typeof value === "number" && Number.isInteger(value) && value > 0;
1960
+ }
1961
+ function rememberStalePid(staleDaemonPids, pid) {
1962
+ if (isPositivePid(pid)) {
1963
+ staleDaemonPids.add(pid);
1964
+ }
1965
+ }
1966
+ async function stopDaemonOnPort(port, token) {
1967
+ try {
1968
+ const response = await fetchWithTimeout(`http://127.0.0.1:${port}/stop`, {
1969
+ method: "POST",
1970
+ headers: { Authorization: `Bearer ${token}` }
1971
+ });
1972
+ return response.ok;
1973
+ } catch {
1974
+ return false;
1975
+ }
1976
+ }
1977
+ async function stopStaleDaemon(port, daemon, staleDaemonPids) {
1978
+ rememberStalePid(staleDaemonPids, daemon.status.pid);
1979
+ const stopped = await stopDaemonOnPort(port, daemon.token);
1980
+ if (!stopped && isPositivePid(daemon.status.pid)) {
1981
+ terminateProcess(daemon.status.pid);
1982
+ }
1983
+ }
1922
1984
  function parseServeArgs(rawArgs) {
1923
1985
  const parsed = { stop: false };
1924
1986
  for (let i = 0; i < rawArgs.length; i += 1) {
@@ -2081,27 +2143,34 @@ async function runServe(args) {
2081
2143
  const metadata = readDaemonMetadata();
2082
2144
  const metadataToken = metadata?.port === requestedPort ? metadata.token : void 0;
2083
2145
  const tokenCandidates = resolveTokenCandidates(serveArgs.token, metadataToken, config.daemonToken);
2146
+ const currentFingerprint = getCurrentDaemonFingerprint();
2084
2147
  const existingDaemon = await resolveExistingDaemon(requestedPort, tokenCandidates);
2085
2148
  const staleDaemonPids = new Set(cleanupCompetingServeProcesses(existingDaemon?.status.pid));
2086
2149
  const staleCleared = () => staleDaemonPids.size;
2150
+ let replacedStaleFingerprint = false;
2087
2151
  if (existingDaemon) {
2088
- const relayPort = existingDaemon.status.relay.port ?? config.relayPort;
2089
- const clearedCount2 = staleCleared();
2090
- const staleNote2 = clearedCount2 > 0 ? `
2152
+ const fingerprintMatches = existingDaemon.status.fingerprint === currentFingerprint;
2153
+ if (fingerprintMatches) {
2154
+ const relayPort = existingDaemon.status.relay.port ?? config.relayPort;
2155
+ const clearedCount2 = staleCleared();
2156
+ const staleNote2 = clearedCount2 > 0 ? `
2091
2157
  Cleared ${clearedCount2} stale daemon process${clearedCount2 === 1 ? "" : "es"}.` : "";
2092
- return {
2093
- success: true,
2094
- message: `Daemon already running on 127.0.0.1:${requestedPort} (pid=${existingDaemon.status.pid}, relay ${relayPort}).${staleNote2}`,
2095
- data: {
2096
- port: requestedPort,
2097
- pid: existingDaemon.status.pid,
2098
- relayPort,
2099
- alreadyRunning: true,
2100
- staleDaemonsCleared: clearedCount2,
2101
- relay: existingDaemon.status.relay
2102
- },
2103
- exitCode: null
2104
- };
2158
+ return {
2159
+ success: true,
2160
+ message: `Daemon already running on 127.0.0.1:${requestedPort} (pid=${existingDaemon.status.pid}, relay ${relayPort}).${staleNote2}`,
2161
+ data: {
2162
+ port: requestedPort,
2163
+ pid: existingDaemon.status.pid,
2164
+ relayPort,
2165
+ alreadyRunning: true,
2166
+ staleDaemonsCleared: clearedCount2,
2167
+ relay: existingDaemon.status.relay
2168
+ },
2169
+ exitCode: null
2170
+ };
2171
+ }
2172
+ await stopStaleDaemon(requestedPort, existingDaemon, staleDaemonPids);
2173
+ replacedStaleFingerprint = true;
2105
2174
  }
2106
2175
  let nativeStatus = getNativeStatusSnapshot();
2107
2176
  let nativeMessage = null;
@@ -2144,23 +2213,31 @@ Cleared ${clearedCount2} stale daemon process${clearedCount2 === 1 ? "" : "es"}.
2144
2213
  }
2145
2214
  const runningDaemon = await resolveExistingDaemon(requestedPort, tokenCandidates);
2146
2215
  if (runningDaemon) {
2147
- const relayPort = runningDaemon.status.relay.port ?? config.relayPort;
2148
- const clearedCount2 = staleCleared();
2149
- const staleNote2 = clearedCount2 > 0 ? `
2216
+ const fingerprintMatches = runningDaemon.status.fingerprint === currentFingerprint;
2217
+ if (fingerprintMatches) {
2218
+ const relayPort = runningDaemon.status.relay.port ?? config.relayPort;
2219
+ const clearedCount2 = staleCleared();
2220
+ const staleNote2 = clearedCount2 > 0 ? `
2150
2221
  Cleared ${clearedCount2} stale daemon process${clearedCount2 === 1 ? "" : "es"}.` : "";
2151
- return {
2152
- success: true,
2153
- message: `Daemon already running on 127.0.0.1:${requestedPort} (pid=${runningDaemon.status.pid}, relay ${relayPort}).${staleNote2}`,
2154
- data: {
2155
- port: requestedPort,
2156
- pid: runningDaemon.status.pid,
2157
- relayPort,
2158
- alreadyRunning: true,
2159
- staleDaemonsCleared: clearedCount2,
2160
- relay: runningDaemon.status.relay
2161
- },
2162
- exitCode: null
2163
- };
2222
+ return {
2223
+ success: true,
2224
+ message: `Daemon already running on 127.0.0.1:${requestedPort} (pid=${runningDaemon.status.pid}, relay ${relayPort}).${staleNote2}`,
2225
+ data: {
2226
+ port: requestedPort,
2227
+ pid: runningDaemon.status.pid,
2228
+ relayPort,
2229
+ alreadyRunning: true,
2230
+ staleDaemonsCleared: clearedCount2,
2231
+ relay: runningDaemon.status.relay
2232
+ },
2233
+ exitCode: null
2234
+ };
2235
+ }
2236
+ await stopStaleDaemon(requestedPort, runningDaemon, staleDaemonPids);
2237
+ replacedStaleFingerprint = true;
2238
+ if (attempt === 0) {
2239
+ continue;
2240
+ }
2164
2241
  }
2165
2242
  if (attempt === 0) {
2166
2243
  let clearedNewPid = false;
@@ -2199,8 +2276,9 @@ Cleared ${clearedCount2} stale daemon process${clearedCount2 === 1 ? "" : "es"}.
2199
2276
  const clearedCount = staleCleared();
2200
2277
  const staleNote = clearedCount > 0 ? `
2201
2278
  Cleared ${clearedCount} stale daemon process${clearedCount === 1 ? "" : "es"}.` : "";
2279
+ const fingerprintNote = replacedStaleFingerprint ? "\nReplaced stale daemon fingerprint." : "";
2202
2280
  const message = nativeMessage ? `${baseMessage}
2203
- ${nativeMessage}${staleNote}` : `${baseMessage}${staleNote}`;
2281
+ ${nativeMessage}${fingerprintNote}${staleNote}` : `${baseMessage}${fingerprintNote}${staleNote}`;
2204
2282
  return {
2205
2283
  success: true,
2206
2284
  message,
@@ -3600,94 +3678,149 @@ async function runSessionDisconnect(args) {
3600
3678
  return { success: true, message: `Session disconnected: ${sessionId}` };
3601
3679
  }
3602
3680
 
3603
- // src/cli/commands/session/inspector.ts
3681
+ // src/cli/utils/workflow-message.ts
3682
+ var asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
3683
+ var readNonEmptyString = (value) => typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
3684
+ var readMeta = (data) => {
3685
+ return asRecord(asRecord(data)?.meta);
3686
+ };
3687
+ var readPrimaryConstraint = (data) => {
3688
+ const meta = readMeta(data);
3689
+ if (!meta) return null;
3690
+ return asRecord(meta.primaryConstraint);
3691
+ };
3692
+ var readPrimarySummary = (data) => {
3693
+ const meta = readMeta(data);
3694
+ return readNonEmptyString(meta?.primaryConstraintSummary);
3695
+ };
3696
+ var readPrimaryNextStep = (data) => {
3697
+ const constraint = readPrimaryConstraint(data);
3698
+ if (!constraint) return null;
3699
+ const guidance = asRecord(constraint.guidance);
3700
+ if (!guidance) return null;
3701
+ const commands = guidance.recommendedNextCommands;
3702
+ if (!Array.isArray(commands)) return null;
3703
+ const nextStep = commands.find((entry) => typeof entry === "string" && entry.trim().length > 0);
3704
+ return nextStep?.trim() ?? null;
3705
+ };
3706
+ var readFailures = (data) => {
3707
+ const meta = readMeta(data);
3708
+ if (!meta) return [];
3709
+ const failures = meta.failures;
3710
+ return Array.isArray(failures) ? failures.filter((entry) => Boolean(entry) && typeof entry === "object") : [];
3711
+ };
3712
+ var readFollowthroughSummary = (data) => {
3713
+ const record = asRecord(data);
3714
+ return readNonEmptyString(record?.followthroughSummary) ?? readNonEmptyString(readMeta(data)?.followthroughSummary);
3715
+ };
3716
+ var readSuggestedSteps = (data) => {
3717
+ const steps = asRecord(data)?.suggestedSteps;
3718
+ return Array.isArray(steps) ? steps.flatMap((step) => {
3719
+ const record = asRecord(step);
3720
+ return record ? [record] : [];
3721
+ }) : [];
3722
+ };
3723
+ var buildNextStepMessage = (message, nextStep) => {
3724
+ return nextStep ? `${message} Next step: ${nextStep}` : message;
3725
+ };
3726
+ var readSuggestedNextAction = (data) => {
3727
+ const record = asRecord(data);
3728
+ if (!record) return null;
3729
+ return readNonEmptyString(record.suggestedNextAction) ?? readNonEmptyString(asRecord(record.sessionInspector)?.suggestedNextAction);
3730
+ };
3731
+ var readSuggestedStepReason = (data) => {
3732
+ let current = asRecord(data);
3733
+ while (current) {
3734
+ const [firstStep] = readSuggestedSteps(current);
3735
+ if (firstStep) {
3736
+ return readNonEmptyString(firstStep.reason);
3737
+ }
3738
+ current = asRecord(current.challengePlan);
3739
+ }
3740
+ return null;
3741
+ };
3742
+ var buildWorkflowCompletionMessage = (workflowLabel, data) => {
3743
+ const explicitSummary = readPrimarySummary(data);
3744
+ if (explicitSummary) {
3745
+ return buildNextStepMessage(
3746
+ `${workflowLabel} completed with provider follow-up required: ${explicitSummary}`,
3747
+ readPrimaryNextStep(data)
3748
+ );
3749
+ }
3750
+ const inferred = summarizePrimaryProviderIssue(readFailures(data));
3751
+ if (inferred) {
3752
+ return buildNextStepMessage(
3753
+ `${workflowLabel} completed with provider follow-up required: ${inferred.summary}`,
3754
+ inferred.guidance?.recommendedNextCommands[0] ?? null
3755
+ );
3756
+ }
3757
+ const followthroughSummary = readFollowthroughSummary(data);
3758
+ if (followthroughSummary) {
3759
+ return buildNextStepMessage(
3760
+ `${workflowLabel} completed. ${followthroughSummary}`,
3761
+ readSuggestedNextAction(data) ?? readSuggestedStepReason(data)
3762
+ );
3763
+ }
3764
+ return `${workflowLabel} completed.`;
3765
+ };
3766
+
3767
+ // src/cli/commands/session/inspector-shared.ts
3604
3768
  function parseSessionInspectorArgs(rawArgs) {
3605
3769
  const parsed = {};
3606
3770
  for (let index = 0; index < rawArgs.length; index += 1) {
3607
3771
  const arg = rawArgs[index];
3608
- if (arg === "--session-id") {
3609
- const value = rawArgs[index + 1];
3610
- if (!value) throw createUsageError("Missing value for --session-id");
3611
- parsed.sessionId = value;
3612
- index += 1;
3613
- continue;
3614
- }
3615
- if (arg?.startsWith("--session-id=")) {
3616
- parsed.sessionId = arg.split("=", 2)[1];
3617
- continue;
3618
- }
3619
3772
  if (arg === "--include-urls") {
3620
3773
  parsed.includeUrls = true;
3621
3774
  continue;
3622
3775
  }
3623
- if (arg === "--since-console-seq") {
3624
- const value = rawArgs[index + 1];
3625
- if (!value) throw createUsageError("Missing value for --since-console-seq");
3626
- parsed.sinceConsoleSeq = parseNumberFlag(value, "--since-console-seq", { min: 0 });
3627
- index += 1;
3776
+ if (arg === "--session-id" || arg?.startsWith("--session-id=")) {
3777
+ parsed.sessionId = readStringFlag(rawArgs, index, "--session-id");
3778
+ index += stepForValue(arg);
3628
3779
  continue;
3629
3780
  }
3630
- if (arg?.startsWith("--since-console-seq=")) {
3631
- const value = arg.split("=", 2)[1];
3632
- if (!value) throw createUsageError("Missing value for --since-console-seq");
3633
- parsed.sinceConsoleSeq = parseNumberFlag(value, "--since-console-seq", { min: 0 });
3781
+ if (arg === "--since-console-seq" || arg?.startsWith("--since-console-seq=")) {
3782
+ parsed.sinceConsoleSeq = readNumberFlag(rawArgs, index, "--since-console-seq", { min: 0 });
3783
+ index += stepForValue(arg);
3634
3784
  continue;
3635
3785
  }
3636
- if (arg === "--since-network-seq") {
3637
- const value = rawArgs[index + 1];
3638
- if (!value) throw createUsageError("Missing value for --since-network-seq");
3639
- parsed.sinceNetworkSeq = parseNumberFlag(value, "--since-network-seq", { min: 0 });
3640
- index += 1;
3786
+ if (arg === "--since-network-seq" || arg?.startsWith("--since-network-seq=")) {
3787
+ parsed.sinceNetworkSeq = readNumberFlag(rawArgs, index, "--since-network-seq", { min: 0 });
3788
+ index += stepForValue(arg);
3641
3789
  continue;
3642
3790
  }
3643
- if (arg?.startsWith("--since-network-seq=")) {
3644
- const value = arg.split("=", 2)[1];
3645
- if (!value) throw createUsageError("Missing value for --since-network-seq");
3646
- parsed.sinceNetworkSeq = parseNumberFlag(value, "--since-network-seq", { min: 0 });
3791
+ if (arg === "--since-exception-seq" || arg?.startsWith("--since-exception-seq=")) {
3792
+ parsed.sinceExceptionSeq = readNumberFlag(rawArgs, index, "--since-exception-seq", { min: 0 });
3793
+ index += stepForValue(arg);
3647
3794
  continue;
3648
3795
  }
3649
- if (arg === "--since-exception-seq") {
3650
- const value = rawArgs[index + 1];
3651
- if (!value) throw createUsageError("Missing value for --since-exception-seq");
3652
- parsed.sinceExceptionSeq = parseNumberFlag(value, "--since-exception-seq", { min: 0 });
3653
- index += 1;
3796
+ if (arg === "--max" || arg?.startsWith("--max=")) {
3797
+ parsed.max = readNumberFlag(rawArgs, index, "--max", { min: 1 });
3798
+ index += stepForValue(arg);
3654
3799
  continue;
3655
3800
  }
3656
- if (arg?.startsWith("--since-exception-seq=")) {
3657
- const value = arg.split("=", 2)[1];
3658
- if (!value) throw createUsageError("Missing value for --since-exception-seq");
3659
- parsed.sinceExceptionSeq = parseNumberFlag(value, "--since-exception-seq", { min: 0 });
3660
- continue;
3661
- }
3662
- if (arg === "--max") {
3663
- const value = rawArgs[index + 1];
3664
- if (!value) throw createUsageError("Missing value for --max");
3665
- parsed.max = parseNumberFlag(value, "--max", { min: 1 });
3666
- index += 1;
3667
- continue;
3668
- }
3669
- if (arg?.startsWith("--max=")) {
3670
- const value = arg.split("=", 2)[1];
3671
- if (!value) throw createUsageError("Missing value for --max");
3672
- parsed.max = parseNumberFlag(value, "--max", { min: 1 });
3673
- continue;
3674
- }
3675
- if (arg === "--request-id") {
3676
- const value = rawArgs[index + 1];
3677
- if (!value) throw createUsageError("Missing value for --request-id");
3678
- parsed.requestId = value;
3679
- index += 1;
3680
- continue;
3681
- }
3682
- if (arg?.startsWith("--request-id=")) {
3683
- const value = arg.split("=", 2)[1];
3684
- if (!value) throw createUsageError("Missing value for --request-id");
3685
- parsed.requestId = value;
3686
- continue;
3801
+ if (arg === "--request-id" || arg?.startsWith("--request-id=")) {
3802
+ parsed.requestId = readStringFlag(rawArgs, index, "--request-id");
3803
+ index += stepForValue(arg);
3687
3804
  }
3688
3805
  }
3689
3806
  return parsed;
3690
3807
  }
3808
+ function stepForValue(flag) {
3809
+ return flag.includes("=") ? 0 : 1;
3810
+ }
3811
+ function readNumberFlag(rawArgs, index, flag, options) {
3812
+ return parseNumberFlag(readStringFlag(rawArgs, index, flag), flag, options);
3813
+ }
3814
+ function readStringFlag(rawArgs, index, flag) {
3815
+ const arg = rawArgs[index];
3816
+ const value = arg?.includes("=") ? arg.split("=", 2)[1] : rawArgs[index + 1];
3817
+ if (!value) {
3818
+ throw createUsageError(`Missing value for ${flag}`);
3819
+ }
3820
+ return value;
3821
+ }
3822
+
3823
+ // src/cli/commands/session/inspector.ts
3691
3824
  async function runSessionInspector(args) {
3692
3825
  const parsed = parseSessionInspectorArgs(args.rawArgs);
3693
3826
  if (!parsed.sessionId) {
@@ -3704,7 +3837,115 @@ async function runSessionInspector(args) {
3704
3837
  });
3705
3838
  return {
3706
3839
  success: true,
3707
- message: "Session inspector snapshot captured.",
3840
+ message: buildNextStepMessage(
3841
+ "Session inspector snapshot captured.",
3842
+ readSuggestedNextAction(result)
3843
+ ),
3844
+ data: result
3845
+ };
3846
+ }
3847
+
3848
+ // src/cli/transport-timeouts.ts
3849
+ var DEFAULT_CLICK_TRANSPORT_TIMEOUT_MS = 6e4;
3850
+ var DEFAULT_DIALOG_TRANSPORT_TIMEOUT_MS = 3e4;
3851
+ var DEFAULT_TARGET_CREATION_TRANSPORT_TIMEOUT_MS = 3e4;
3852
+ var DEFAULT_SNAPSHOT_TRANSPORT_TIMEOUT_MS = 3e4;
3853
+ var DEFAULT_REVIEW_TRANSPORT_TIMEOUT_MS = 3e4;
3854
+ var DEFAULT_SCREENSHOT_TRANSPORT_TIMEOUT_MS = 3e4;
3855
+ var DEFAULT_WORKFLOW_TRANSPORT_TIMEOUT_MS = 12e4;
3856
+
3857
+ // src/cli/commands/challenge-automation-mode.ts
3858
+ function parseOptionalChallengeAutomationMode(rawArgs) {
3859
+ const value = parseOptionalStringFlag(rawArgs, "--challenge-automation-mode");
3860
+ if (typeof value === "undefined") {
3861
+ return void 0;
3862
+ }
3863
+ if (!isChallengeAutomationMode(value)) {
3864
+ throw createUsageError(`Invalid --challenge-automation-mode: ${value}`);
3865
+ }
3866
+ return value;
3867
+ }
3868
+
3869
+ // src/cli/commands/nav/review-shared.ts
3870
+ function parseOptionalNumberFlag(rawArgs, flag, options) {
3871
+ const value = parseOptionalStringFlag(rawArgs, flag);
3872
+ return typeof value === "string" ? parseNumberFlag(value, flag, options) : void 0;
3873
+ }
3874
+ function parseReviewCommandArgs(rawArgs) {
3875
+ return {
3876
+ sessionId: parseOptionalStringFlag(rawArgs, "--session-id"),
3877
+ targetId: parseOptionalStringFlag(rawArgs, "--target-id"),
3878
+ reason: parseOptionalStringFlag(rawArgs, "--reason"),
3879
+ maxChars: parseOptionalNumberFlag(rawArgs, "--max-chars", { min: 1 }),
3880
+ cursor: parseOptionalStringFlag(rawArgs, "--cursor"),
3881
+ timeoutMs: parseOptionalNumberFlag(rawArgs, "--timeout-ms", { min: 1 })
3882
+ };
3883
+ }
3884
+
3885
+ // src/cli/commands/session/inspector-audit.ts
3886
+ function parseOptionalTimeoutMs(rawArgs) {
3887
+ const value = parseOptionalStringFlag(rawArgs, "--timeout-ms");
3888
+ return typeof value === "string" ? parseNumberFlag(value, "--timeout-ms", { min: 1 }) : void 0;
3889
+ }
3890
+ async function runSessionInspectorAudit(args) {
3891
+ const reviewArgs = parseReviewCommandArgs(args.rawArgs);
3892
+ const inspectorArgs = parseSessionInspectorArgs(args.rawArgs);
3893
+ const challengeAutomationMode = parseOptionalChallengeAutomationMode(args.rawArgs);
3894
+ const timeoutMs = parseOptionalTimeoutMs(args.rawArgs);
3895
+ const sessionId = reviewArgs.sessionId ?? inspectorArgs.sessionId;
3896
+ if (!sessionId) {
3897
+ throw createUsageError("Missing --session-id");
3898
+ }
3899
+ const result = await callDaemon("session.inspectAudit", {
3900
+ sessionId,
3901
+ ...typeof reviewArgs.targetId === "string" ? { targetId: reviewArgs.targetId } : {},
3902
+ ...typeof reviewArgs.reason === "string" ? { reason: reviewArgs.reason } : {},
3903
+ ...typeof reviewArgs.maxChars === "number" ? { maxChars: reviewArgs.maxChars } : {},
3904
+ ...typeof reviewArgs.cursor === "string" ? { cursor: reviewArgs.cursor } : {},
3905
+ ...typeof inspectorArgs.includeUrls === "boolean" ? { includeUrls: inspectorArgs.includeUrls } : {},
3906
+ ...typeof inspectorArgs.sinceConsoleSeq === "number" ? { sinceConsoleSeq: inspectorArgs.sinceConsoleSeq } : {},
3907
+ ...typeof inspectorArgs.sinceNetworkSeq === "number" ? { sinceNetworkSeq: inspectorArgs.sinceNetworkSeq } : {},
3908
+ ...typeof inspectorArgs.sinceExceptionSeq === "number" ? { sinceExceptionSeq: inspectorArgs.sinceExceptionSeq } : {},
3909
+ ...typeof inspectorArgs.max === "number" ? { max: inspectorArgs.max } : {},
3910
+ ...typeof inspectorArgs.requestId === "string" ? { requestId: inspectorArgs.requestId } : {},
3911
+ ...challengeAutomationMode ? { challengeAutomationMode } : {}
3912
+ }, {
3913
+ timeoutMs: timeoutMs ?? DEFAULT_REVIEW_TRANSPORT_TIMEOUT_MS
3914
+ });
3915
+ const nextStep = readSuggestedNextAction(result) ?? readSuggestedStepReason(result);
3916
+ return {
3917
+ success: true,
3918
+ message: buildNextStepMessage("Correlated audit bundle captured.", nextStep),
3919
+ data: result
3920
+ };
3921
+ }
3922
+
3923
+ // src/cli/commands/session/inspector-plan.ts
3924
+ function parseOptionalTimeoutMs2(rawArgs) {
3925
+ const value = parseOptionalStringFlag(rawArgs, "--timeout-ms");
3926
+ return typeof value === "string" ? parseNumberFlag(value, "--timeout-ms", { min: 1 }) : void 0;
3927
+ }
3928
+ async function runSessionInspectorPlan(args) {
3929
+ const sessionId = parseOptionalStringFlag(args.rawArgs, "--session-id");
3930
+ const targetId = parseOptionalStringFlag(args.rawArgs, "--target-id");
3931
+ const challengeAutomationMode = parseOptionalChallengeAutomationMode(args.rawArgs);
3932
+ const timeoutMs = parseOptionalTimeoutMs2(args.rawArgs);
3933
+ if (!sessionId) {
3934
+ throw createUsageError("Missing --session-id");
3935
+ }
3936
+ const result = await callDaemon("session.inspectPlan", {
3937
+ sessionId,
3938
+ ...typeof targetId === "string" ? { targetId } : {},
3939
+ ...challengeAutomationMode ? { challengeAutomationMode } : {}
3940
+ }, {
3941
+ timeoutMs: timeoutMs ?? DEFAULT_REVIEW_TRANSPORT_TIMEOUT_MS
3942
+ });
3943
+ return {
3944
+ success: true,
3945
+ message: buildNextStepMessage(
3946
+ "Challenge inspect plan captured.",
3947
+ readSuggestedStepReason(result)
3948
+ ),
3708
3949
  data: result
3709
3950
  };
3710
3951
  }
@@ -3811,6 +4052,30 @@ async function runStatus(args) {
3811
4052
  };
3812
4053
  }
3813
4054
 
4055
+ // src/cli/commands/status-capabilities.ts
4056
+ function parseOptionalTimeoutMs3(rawArgs) {
4057
+ const value = parseOptionalStringFlag(rawArgs, "--timeout-ms");
4058
+ return typeof value === "string" ? parseNumberFlag(value, "--timeout-ms", { min: 1 }) : void 0;
4059
+ }
4060
+ async function runStatusCapabilities(args) {
4061
+ const sessionId = parseOptionalStringFlag(args.rawArgs, "--session-id");
4062
+ const targetId = parseOptionalStringFlag(args.rawArgs, "--target-id");
4063
+ const challengeAutomationMode = parseOptionalChallengeAutomationMode(args.rawArgs);
4064
+ const timeoutMs = parseOptionalTimeoutMs3(args.rawArgs);
4065
+ const result = await callDaemon("status.capabilities", {
4066
+ ...typeof sessionId === "string" ? { sessionId } : {},
4067
+ ...typeof targetId === "string" ? { targetId } : {},
4068
+ ...challengeAutomationMode ? { challengeAutomationMode } : {}
4069
+ }, {
4070
+ timeoutMs: timeoutMs ?? DEFAULT_REVIEW_TRANSPORT_TIMEOUT_MS
4071
+ });
4072
+ return {
4073
+ success: true,
4074
+ message: "Capability discovery captured.",
4075
+ data: result
4076
+ };
4077
+ }
4078
+
3814
4079
  // src/cli/commands/nav/goto.ts
3815
4080
  function parseGotoArgs(rawArgs) {
3816
4081
  const parsed = {};
@@ -3960,15 +4225,6 @@ async function runWait(args) {
3960
4225
  return { success: true, message: "Wait complete.", data: result };
3961
4226
  }
3962
4227
 
3963
- // src/cli/transport-timeouts.ts
3964
- var DEFAULT_CLICK_TRANSPORT_TIMEOUT_MS = 6e4;
3965
- var DEFAULT_DIALOG_TRANSPORT_TIMEOUT_MS = 3e4;
3966
- var DEFAULT_TARGET_CREATION_TRANSPORT_TIMEOUT_MS = 3e4;
3967
- var DEFAULT_SNAPSHOT_TRANSPORT_TIMEOUT_MS = 3e4;
3968
- var DEFAULT_REVIEW_TRANSPORT_TIMEOUT_MS = 3e4;
3969
- var DEFAULT_SCREENSHOT_TRANSPORT_TIMEOUT_MS = 3e4;
3970
- var DEFAULT_WORKFLOW_TRANSPORT_TIMEOUT_MS = 12e4;
3971
-
3972
4228
  // src/cli/commands/nav/snapshot.ts
3973
4229
  function parseSnapshotArgs(rawArgs) {
3974
4230
  const parsed = {};
@@ -4051,61 +4307,8 @@ async function runSnapshot(args) {
4051
4307
  }
4052
4308
 
4053
4309
  // src/cli/commands/nav/review.ts
4054
- function parseReviewArgs(rawArgs) {
4055
- const parsed = {};
4056
- for (let i = 0; i < rawArgs.length; i += 1) {
4057
- const arg = rawArgs[i];
4058
- if (arg === "--session-id") {
4059
- const value = rawArgs[i + 1];
4060
- if (!value) throw createUsageError("Missing value for --session-id");
4061
- parsed.sessionId = value;
4062
- i += 1;
4063
- continue;
4064
- }
4065
- if (arg?.startsWith("--session-id=")) {
4066
- parsed.sessionId = arg.split("=", 2)[1];
4067
- continue;
4068
- }
4069
- if (arg === "--max-chars") {
4070
- const value = rawArgs[i + 1];
4071
- if (!value) throw createUsageError("Missing value for --max-chars");
4072
- parsed.maxChars = Number(value);
4073
- i += 1;
4074
- continue;
4075
- }
4076
- if (arg?.startsWith("--max-chars=")) {
4077
- parsed.maxChars = Number(arg.split("=", 2)[1]);
4078
- continue;
4079
- }
4080
- if (arg === "--cursor") {
4081
- const value = rawArgs[i + 1];
4082
- if (!value) throw createUsageError("Missing value for --cursor");
4083
- parsed.cursor = value;
4084
- i += 1;
4085
- continue;
4086
- }
4087
- if (arg?.startsWith("--cursor=")) {
4088
- parsed.cursor = arg.split("=", 2)[1];
4089
- continue;
4090
- }
4091
- if (arg === "--timeout-ms") {
4092
- const value = rawArgs[i + 1];
4093
- if (!value) throw createUsageError("Missing value for --timeout-ms");
4094
- parsed.timeoutMs = parseNumberFlag(value, "--timeout-ms", { min: 1 });
4095
- i += 1;
4096
- continue;
4097
- }
4098
- if (arg?.startsWith("--timeout-ms=")) {
4099
- const value = arg.split("=", 2)[1];
4100
- if (!value) throw createUsageError("Missing value for --timeout-ms");
4101
- parsed.timeoutMs = parseNumberFlag(value, "--timeout-ms", { min: 1 });
4102
- }
4103
- }
4104
- return parsed;
4105
- }
4106
4310
  async function runReview(args) {
4107
- const { sessionId, maxChars, cursor, timeoutMs } = parseReviewArgs(args.rawArgs);
4108
- const targetId = parseOptionalStringFlag(args.rawArgs, "--target-id");
4311
+ const { sessionId, targetId, maxChars, cursor, timeoutMs } = parseReviewCommandArgs(args.rawArgs);
4109
4312
  if (!sessionId) throw createUsageError("Missing --session-id");
4110
4313
  const payload = {
4111
4314
  sessionId,
@@ -4119,6 +4322,28 @@ async function runReview(args) {
4119
4322
  return { success: true, message: "Review captured.", data: result };
4120
4323
  }
4121
4324
 
4325
+ // src/cli/commands/nav/review-desktop.ts
4326
+ async function runReviewDesktop(args) {
4327
+ const { sessionId, targetId, reason, maxChars, cursor, timeoutMs } = parseReviewCommandArgs(args.rawArgs);
4328
+ if (!sessionId) {
4329
+ throw createUsageError("Missing --session-id");
4330
+ }
4331
+ const result = await callDaemon("nav.reviewDesktop", {
4332
+ sessionId,
4333
+ ...typeof targetId === "string" ? { targetId } : {},
4334
+ ...typeof reason === "string" ? { reason } : {},
4335
+ ...typeof maxChars === "number" ? { maxChars } : {},
4336
+ ...typeof cursor === "string" ? { cursor } : {}
4337
+ }, {
4338
+ timeoutMs: timeoutMs ?? DEFAULT_REVIEW_TRANSPORT_TIMEOUT_MS
4339
+ });
4340
+ return {
4341
+ success: true,
4342
+ message: "Desktop-assisted review captured.",
4343
+ data: result
4344
+ };
4345
+ }
4346
+
4122
4347
  // src/cli/commands/annotate.ts
4123
4348
  var requireValue2 = (value, flag) => {
4124
4349
  if (!value) throw createUsageError(`Missing value for ${flag}`);
@@ -6660,12 +6885,39 @@ async function runCookieList(args) {
6660
6885
  }
6661
6886
 
6662
6887
  // src/cli/commands/macro-resolve.ts
6888
+ var MACRO_TRANSPORT_TIMEOUT_BUFFER_MS = 6e4;
6889
+ var deriveMacroTransportTimeoutMs = (timeoutMs) => {
6890
+ return Math.max(
6891
+ DEFAULT_WORKFLOW_TRANSPORT_TIMEOUT_MS,
6892
+ timeoutMs + MACRO_TRANSPORT_TIMEOUT_BUFFER_MS
6893
+ );
6894
+ };
6663
6895
  var requireValue7 = (value, flag) => {
6664
6896
  if (!value) {
6665
6897
  throw createUsageError(`Missing value for ${flag}`);
6666
6898
  }
6667
6899
  return value;
6668
6900
  };
6901
+ var asRecord2 = (value) => {
6902
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
6903
+ return null;
6904
+ }
6905
+ return value;
6906
+ };
6907
+ var hasExecutionBlocker = (result) => {
6908
+ const execution = asRecord2(asRecord2(result)?.execution);
6909
+ const meta = asRecord2(execution?.meta);
6910
+ return asRecord2(meta?.blocker) !== null;
6911
+ };
6912
+ var buildMacroResolveMessage = (execute, result) => {
6913
+ if (!execute) {
6914
+ return "Macro resolved.";
6915
+ }
6916
+ if (hasExecutionBlocker(result)) {
6917
+ return "Macro resolved, but execution is blocked and needs follow-up.";
6918
+ }
6919
+ return "Macro resolved and executed.";
6920
+ };
6669
6921
  var parseMacroResolveArgs = (rawArgs) => {
6670
6922
  const parsed = {};
6671
6923
  for (let index = 0; index < rawArgs.length; index += 1) {
@@ -6739,44 +6991,16 @@ async function runMacroResolve(args) {
6739
6991
  ...typeof parsed.timeoutMs === "number" ? { timeoutMs: parsed.timeoutMs } : {},
6740
6992
  ...parsed.challengeAutomationMode ? { challengeAutomationMode: parsed.challengeAutomationMode } : {}
6741
6993
  };
6742
- const result = typeof parsed.timeoutMs === "number" ? await callDaemon("macro.resolve", params, { timeoutMs: parsed.timeoutMs }) : await callDaemon("macro.resolve", params);
6994
+ const result = typeof parsed.timeoutMs === "number" ? await callDaemon("macro.resolve", params, {
6995
+ timeoutMs: deriveMacroTransportTimeoutMs(parsed.timeoutMs)
6996
+ }) : await callDaemon("macro.resolve", params);
6743
6997
  return {
6744
6998
  success: true,
6745
- message: parsed.execute ? "Macro resolved and executed." : "Macro resolved.",
6999
+ message: buildMacroResolveMessage(parsed.execute ?? false, result),
6746
7000
  data: result
6747
7001
  };
6748
7002
  }
6749
7003
 
6750
- // src/cli/utils/workflow-message.ts
6751
- var readMeta = (data) => {
6752
- if (!data || typeof data !== "object" || Array.isArray(data)) return null;
6753
- const meta = data.meta;
6754
- return meta && typeof meta === "object" && !Array.isArray(meta) ? meta : null;
6755
- };
6756
- var readPrimarySummary = (data) => {
6757
- const meta = readMeta(data);
6758
- if (!meta) return null;
6759
- const summary = meta.primaryConstraintSummary;
6760
- return typeof summary === "string" && summary.trim().length > 0 ? summary.trim() : null;
6761
- };
6762
- var readFailures = (data) => {
6763
- const meta = readMeta(data);
6764
- if (!meta) return [];
6765
- const failures = meta.failures;
6766
- return Array.isArray(failures) ? failures.filter((entry) => Boolean(entry) && typeof entry === "object") : [];
6767
- };
6768
- var buildWorkflowCompletionMessage = (workflowLabel, data) => {
6769
- const explicitSummary = readPrimarySummary(data);
6770
- if (explicitSummary) {
6771
- return `${workflowLabel} completed with provider follow-up required: ${explicitSummary}`;
6772
- }
6773
- const inferred = summarizePrimaryProviderIssue(readFailures(data));
6774
- if (inferred) {
6775
- return `${workflowLabel} completed with provider follow-up required: ${inferred.summary}`;
6776
- }
6777
- return `${workflowLabel} completed.`;
6778
- };
6779
-
6780
7004
  // src/cli/commands/research.ts
6781
7005
  var SOURCE_VALUES = /* @__PURE__ */ new Set(["web", "community", "social", "shopping"]);
6782
7006
  var SOURCE_SELECTION_VALUES = /* @__PURE__ */ new Set(["auto", "web", "community", "social", "shopping", "all"]);
@@ -7409,10 +7633,177 @@ async function runProductVideoCommand(args) {
7409
7633
  };
7410
7634
  }
7411
7635
 
7636
+ // src/cli/commands/inspiredesign.ts
7637
+ var MODE_VALUES3 = /* @__PURE__ */ new Set(["compact", "json", "md", "context", "path"]);
7638
+ var CAPTURE_MODE_VALUES = /* @__PURE__ */ new Set(["off", "deep"]);
7639
+ var COOKIE_POLICY_VALUES4 = /* @__PURE__ */ new Set(["off", "auto", "required"]);
7640
+ var requireValue11 = (rawArgs, index, flag) => {
7641
+ const value = rawArgs[index + 1];
7642
+ if (!value) {
7643
+ throw createUsageError(`Missing value for ${flag}`);
7644
+ }
7645
+ return value;
7646
+ };
7647
+ var parseInspiredesignRunArgs = (rawArgs) => {
7648
+ const parsed = {
7649
+ brief: parseOptionalStringFlag(rawArgs, "--brief"),
7650
+ urls: parseRepeatedStringFlag(rawArgs, "--url")
7651
+ };
7652
+ for (let index = 0; index < rawArgs.length; index += 1) {
7653
+ const arg = rawArgs[index];
7654
+ if (arg === "--brief" || arg === "--url") {
7655
+ index += 1;
7656
+ continue;
7657
+ }
7658
+ if (arg?.startsWith("--brief=") || arg?.startsWith("--url=")) {
7659
+ continue;
7660
+ }
7661
+ if (arg === "--capture-mode") {
7662
+ const value = requireValue11(rawArgs, index, "--capture-mode").toLowerCase();
7663
+ if (!CAPTURE_MODE_VALUES.has(value)) {
7664
+ throw createUsageError(`Invalid --capture-mode: ${value}`);
7665
+ }
7666
+ parsed.captureMode = value;
7667
+ index += 1;
7668
+ continue;
7669
+ }
7670
+ if (arg?.startsWith("--capture-mode=")) {
7671
+ const value = (arg.split("=", 2)[1] ?? "").toLowerCase();
7672
+ if (!CAPTURE_MODE_VALUES.has(value)) {
7673
+ throw createUsageError(`Invalid --capture-mode: ${value}`);
7674
+ }
7675
+ parsed.captureMode = value;
7676
+ continue;
7677
+ }
7678
+ if (arg === "--include-prototype-guidance") {
7679
+ parsed.includePrototypeGuidance = true;
7680
+ continue;
7681
+ }
7682
+ if (arg?.startsWith("--include-prototype-guidance=")) {
7683
+ parsed.includePrototypeGuidance = parseBooleanFlag(arg.split("=", 2)[1] ?? "", "--include-prototype-guidance");
7684
+ continue;
7685
+ }
7686
+ if (arg === "--mode") {
7687
+ const value = requireValue11(rawArgs, index, "--mode").toLowerCase();
7688
+ if (!MODE_VALUES3.has(value)) {
7689
+ throw createUsageError(`Invalid --mode: ${value}`);
7690
+ }
7691
+ parsed.mode = value;
7692
+ index += 1;
7693
+ continue;
7694
+ }
7695
+ if (arg?.startsWith("--mode=")) {
7696
+ const value = (arg.split("=", 2)[1] ?? "").toLowerCase();
7697
+ if (!MODE_VALUES3.has(value)) {
7698
+ throw createUsageError(`Invalid --mode: ${value}`);
7699
+ }
7700
+ parsed.mode = value;
7701
+ continue;
7702
+ }
7703
+ if (arg === "--timeout-ms") {
7704
+ parsed.timeoutMs = parseNumberFlag(requireValue11(rawArgs, index, "--timeout-ms"), "--timeout-ms", { min: 1 });
7705
+ index += 1;
7706
+ continue;
7707
+ }
7708
+ if (arg?.startsWith("--timeout-ms=")) {
7709
+ parsed.timeoutMs = parseNumberFlag(arg.split("=", 2)[1] ?? "", "--timeout-ms", { min: 1 });
7710
+ continue;
7711
+ }
7712
+ if (arg === "--output-dir") {
7713
+ parsed.outputDir = requireValue11(rawArgs, index, "--output-dir");
7714
+ index += 1;
7715
+ continue;
7716
+ }
7717
+ if (arg?.startsWith("--output-dir=")) {
7718
+ parsed.outputDir = arg.split("=", 2)[1];
7719
+ continue;
7720
+ }
7721
+ if (arg === "--ttl-hours") {
7722
+ parsed.ttlHours = parseNumberFlag(requireValue11(rawArgs, index, "--ttl-hours"), "--ttl-hours", { min: 1, max: 168 });
7723
+ index += 1;
7724
+ continue;
7725
+ }
7726
+ if (arg?.startsWith("--ttl-hours=")) {
7727
+ parsed.ttlHours = parseNumberFlag(arg.split("=", 2)[1] ?? "", "--ttl-hours", { min: 1, max: 168 });
7728
+ continue;
7729
+ }
7730
+ if (arg === "--use-cookies") {
7731
+ parsed.useCookies = true;
7732
+ continue;
7733
+ }
7734
+ if (arg?.startsWith("--use-cookies=")) {
7735
+ parsed.useCookies = parseBooleanFlag(arg.split("=", 2)[1] ?? "", "--use-cookies");
7736
+ continue;
7737
+ }
7738
+ if (arg === "--challenge-automation-mode") {
7739
+ const value = requireValue11(rawArgs, index, "--challenge-automation-mode");
7740
+ if (!isChallengeAutomationMode(value)) {
7741
+ throw createUsageError(`Invalid --challenge-automation-mode: ${value}`);
7742
+ }
7743
+ parsed.challengeAutomationMode = value;
7744
+ index += 1;
7745
+ continue;
7746
+ }
7747
+ if (arg?.startsWith("--challenge-automation-mode=")) {
7748
+ const value = arg.split("=", 2)[1] ?? "";
7749
+ if (!isChallengeAutomationMode(value)) {
7750
+ throw createUsageError(`Invalid --challenge-automation-mode: ${value}`);
7751
+ }
7752
+ parsed.challengeAutomationMode = value;
7753
+ continue;
7754
+ }
7755
+ if (arg === "--cookie-policy-override" || arg === "--cookie-policy") {
7756
+ const value = requireValue11(rawArgs, index, arg).toLowerCase();
7757
+ if (!COOKIE_POLICY_VALUES4.has(value)) {
7758
+ throw createUsageError(`Invalid ${arg}: ${value}`);
7759
+ }
7760
+ parsed.cookiePolicyOverride = value;
7761
+ index += 1;
7762
+ continue;
7763
+ }
7764
+ if (arg?.startsWith("--cookie-policy-override=") || arg?.startsWith("--cookie-policy=")) {
7765
+ const value = (arg.split("=", 2)[1] ?? "").toLowerCase();
7766
+ if (!COOKIE_POLICY_VALUES4.has(value)) {
7767
+ throw createUsageError(`Invalid --cookie-policy-override: ${value}`);
7768
+ }
7769
+ parsed.cookiePolicyOverride = value;
7770
+ }
7771
+ }
7772
+ return parsed;
7773
+ };
7774
+ async function runInspiredesignCommand(args) {
7775
+ const [subcommand, ...rest] = args.rawArgs;
7776
+ if (subcommand !== "run") {
7777
+ throw createUsageError("Usage: opendevbrowser inspiredesign run --brief <value> [--url <url>] [options]");
7778
+ }
7779
+ const parsed = parseInspiredesignRunArgs(rest);
7780
+ if (!parsed.brief?.trim()) {
7781
+ throw createUsageError("Missing --brief");
7782
+ }
7783
+ const data = await callDaemon("inspiredesign.run", {
7784
+ brief: parsed.brief,
7785
+ urls: parsed.urls,
7786
+ captureMode: parsed.captureMode ?? "off",
7787
+ includePrototypeGuidance: parsed.includePrototypeGuidance,
7788
+ mode: parsed.mode ?? "compact",
7789
+ timeoutMs: parsed.timeoutMs ?? DEFAULT_WORKFLOW_TRANSPORT_TIMEOUT_MS,
7790
+ outputDir: parsed.outputDir,
7791
+ ttlHours: parsed.ttlHours,
7792
+ useCookies: parsed.useCookies,
7793
+ challengeAutomationMode: parsed.challengeAutomationMode,
7794
+ cookiePolicyOverride: parsed.cookiePolicyOverride
7795
+ });
7796
+ return {
7797
+ success: true,
7798
+ message: buildWorkflowCompletionMessage("Inspiredesign workflow", data),
7799
+ data
7800
+ };
7801
+ }
7802
+
7412
7803
  // package.json
7413
7804
  var package_default = {
7414
7805
  name: "opendevbrowser",
7415
- version: "0.0.19",
7806
+ version: "0.0.21",
7416
7807
  description: "Browser automation runtime with snapshot-refs-actions, browser replay screencasts, public read-only desktop observation, and browser-scoped computer-use orchestration",
7417
7808
  type: "module",
7418
7809
  main: "dist/index.js",
@@ -7457,10 +7848,10 @@ var package_default = {
7457
7848
  node: ">=18"
7458
7849
  },
7459
7850
  scripts: {
7460
- build: "tsup src/index.ts src/cli/index.ts src/skills/skill-loader.ts --format esm --clean --sourcemap && tsc --emitDeclarationOnly --declaration --declarationMap -p tsconfig.json && node scripts/postbuild-dist.mjs",
7851
+ build: "node scripts/run-package-tool.mjs tsup src/index.ts src/cli/index.ts src/skills/skill-loader.ts --format esm --clean --sourcemap && node scripts/run-package-tool.mjs tsc --emitDeclarationOnly --declaration --declarationMap -p tsconfig.json && node scripts/postbuild-dist.mjs",
7461
7852
  dev: "tsup src/index.ts src/cli/index.ts src/skills/skill-loader.ts --format esm --dts --watch",
7462
- lint: 'eslint "src/**/*.ts" "tests/**/*.ts"',
7463
- typecheck: "tsc --noEmit -p tsconfig.json",
7853
+ lint: 'node scripts/run-package-tool.mjs eslint "src/**/*.ts" "tests/**/*.ts"',
7854
+ typecheck: "node scripts/run-package-tool.mjs tsc --noEmit -p tsconfig.json",
7464
7855
  test: "node scripts/run-vitest-coverage.mjs",
7465
7856
  "test:release-gate": "node scripts/release-gate-test-groups.mjs",
7466
7857
  "test:release-gate:g1": "node scripts/release-gate-test-groups.mjs --group 1",
@@ -7469,7 +7860,7 @@ var package_default = {
7469
7860
  "test:release-gate:g4": "node scripts/release-gate-test-groups.mjs --group 4",
7470
7861
  "test:release-gate:g5": "node scripts/release-gate-test-groups.mjs --group 5",
7471
7862
  "extension:sync": "node scripts/sync-extension-version.mjs",
7472
- "extension:build": "npm run extension:sync && tsc -p extension/tsconfig.json && node scripts/copy-extension-assets.mjs",
7863
+ "extension:build": "npm run extension:sync && node scripts/run-package-tool.mjs tsc -p extension/tsconfig.json && node scripts/copy-extension-assets.mjs",
7473
7864
  "extension:pack": "cd extension && zip -r ../opendevbrowser-extension.zip manifest.json popup.html canvas.html dist/ icons/",
7474
7865
  "extension:store": "node scripts/chrome-store-publish.mjs",
7475
7866
  "version:check": "node scripts/verify-versions.mjs",
@@ -7833,11 +8224,26 @@ async function main() {
7833
8224
  description: "Get daemon or session status",
7834
8225
  run: async () => runStatus(args)
7835
8226
  });
8227
+ registerCommand({
8228
+ name: "status-capabilities",
8229
+ description: "Inspect runtime capability discovery for the host and an optional session",
8230
+ run: async () => runStatusCapabilities(args)
8231
+ });
7836
8232
  registerCommand({
7837
8233
  name: "session-inspector",
7838
8234
  description: "Capture a session-first diagnostic summary with relay health and trace proof",
7839
8235
  run: async () => runSessionInspector(args)
7840
8236
  });
8237
+ registerCommand({
8238
+ name: "session-inspector-plan",
8239
+ description: "Inspect browser-scoped computer-use policy and safe suggested steps",
8240
+ run: async () => runSessionInspectorPlan(args)
8241
+ });
8242
+ registerCommand({
8243
+ name: "session-inspector-audit",
8244
+ description: "Capture a correlated audit bundle across desktop evidence, browser review, and policy state",
8245
+ run: async () => runSessionInspectorAudit(args)
8246
+ });
7841
8247
  registerCommand({
7842
8248
  name: "goto",
7843
8249
  description: "Navigate current session to a URL",
@@ -7858,6 +8264,11 @@ async function main() {
7858
8264
  description: "Capture a first-class review payload for the active page",
7859
8265
  run: async () => runReview(args)
7860
8266
  });
8267
+ registerCommand({
8268
+ name: "review-desktop",
8269
+ description: "Capture desktop-assisted browser review with read-only desktop evidence",
8270
+ run: async () => runReviewDesktop(args)
8271
+ });
7861
8272
  registerCommand({
7862
8273
  name: "annotate",
7863
8274
  description: "Request interactive annotations via direct or relay transport",
@@ -8123,6 +8534,11 @@ async function main() {
8123
8534
  description: "Run product presentation asset workflows",
8124
8535
  run: async () => runProductVideoCommand(args)
8125
8536
  });
8537
+ registerCommand({
8538
+ name: "inspiredesign",
8539
+ description: "Run inspiredesign workflows",
8540
+ run: async () => runInspiredesignCommand(args)
8541
+ });
8126
8542
  registerCommand({
8127
8543
  name: "artifacts",
8128
8544
  description: "Manage workflow artifact lifecycle",