opendevbrowser 0.0.19 → 0.0.20

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 (168) 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-5FZQJRBQ.js → chunk-C6QUKABT.js} +2789 -992
  34. package/dist/chunk-C6QUKABT.js.map +1 -0
  35. package/dist/{chunk-W4IHGDXV.js → chunk-LMNFPJRI.js} +4256 -2759
  36. package/dist/chunk-LMNFPJRI.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 +614 -242
  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 +728 -447
  87. package/dist/index.js.map +1 -1
  88. package/dist/opendevbrowser.d.ts.map +1 -1
  89. package/dist/opendevbrowser.js +728 -447
  90. package/dist/opendevbrowser.js.map +1 -1
  91. package/dist/providers/browser-fallback.d.ts.map +1 -1
  92. package/dist/providers/constraint.d.ts +11 -0
  93. package/dist/providers/constraint.d.ts.map +1 -1
  94. package/dist/providers/cookie-source.d.ts +8 -0
  95. package/dist/providers/cookie-source.d.ts.map +1 -0
  96. package/dist/providers/index.d.ts.map +1 -1
  97. package/dist/providers/inspiredesign-capture.d.ts +17 -0
  98. package/dist/providers/inspiredesign-capture.d.ts.map +1 -0
  99. package/dist/providers/inspiredesign-contract.d.ts +77 -0
  100. package/dist/providers/inspiredesign-contract.d.ts.map +1 -0
  101. package/dist/providers/renderer.d.ts +21 -0
  102. package/dist/providers/renderer.d.ts.map +1 -1
  103. package/dist/providers/runtime-bundle.d.ts +2 -1
  104. package/dist/providers/runtime-bundle.d.ts.map +1 -1
  105. package/dist/providers/runtime-factory.d.ts +4 -2
  106. package/dist/providers/runtime-factory.d.ts.map +1 -1
  107. package/dist/providers/shopping/index.d.ts +1 -1
  108. package/dist/providers/types.d.ts +3 -2
  109. package/dist/providers/types.d.ts.map +1 -1
  110. package/dist/providers/workflow-contracts.d.ts +1 -1
  111. package/dist/providers/workflow-contracts.d.ts.map +1 -1
  112. package/dist/providers/workflows.d.ts +21 -2
  113. package/dist/providers/workflows.d.ts.map +1 -1
  114. package/dist/{providers-G36AM3Z2.js → providers-3VBLTNAX.js} +6 -2
  115. package/dist/public-surface/generated-manifest.d.ts +143 -7
  116. package/dist/public-surface/generated-manifest.d.ts.map +1 -1
  117. package/dist/public-surface/source.d.ts +102 -3
  118. package/dist/public-surface/source.d.ts.map +1 -1
  119. package/dist/relay/protocol.d.ts +1 -1
  120. package/dist/relay/protocol.d.ts.map +1 -1
  121. package/dist/relay/relay-server.d.ts +1 -0
  122. package/dist/relay/relay-server.d.ts.map +1 -1
  123. package/dist/skills/skill-loader.js +1 -1
  124. package/dist/tools/automation-shared.d.ts +6 -0
  125. package/dist/tools/automation-shared.d.ts.map +1 -0
  126. package/dist/tools/index.d.ts.map +1 -1
  127. package/dist/tools/inspiredesign_run.d.ts +4 -0
  128. package/dist/tools/inspiredesign_run.d.ts.map +1 -0
  129. package/dist/tools/review_desktop.d.ts +4 -0
  130. package/dist/tools/review_desktop.d.ts.map +1 -0
  131. package/dist/tools/session_inspector.d.ts.map +1 -1
  132. package/dist/tools/session_inspector_audit.d.ts +4 -0
  133. package/dist/tools/session_inspector_audit.d.ts.map +1 -0
  134. package/dist/tools/session_inspector_plan.d.ts +4 -0
  135. package/dist/tools/session_inspector_plan.d.ts.map +1 -0
  136. package/dist/tools/status_capabilities.d.ts +4 -0
  137. package/dist/tools/status_capabilities.d.ts.map +1 -0
  138. package/extension/dist/background.js +70 -10
  139. package/extension/dist/canvas/canvas-runtime.js +14 -1
  140. package/extension/dist/ops/ops-runtime.js +18 -1
  141. package/extension/dist/popup.js +29 -16
  142. package/extension/dist/services/ConnectionManager.js +27 -2
  143. package/extension/manifest.json +1 -1
  144. package/extension/popup.html +11 -0
  145. package/package.json +5 -5
  146. package/skills/AGENTS.md +2 -2
  147. package/skills/opendevbrowser-best-practices/SKILL.md +50 -15
  148. package/skills/opendevbrowser-best-practices/artifacts/canvas-governance-playbook.md +31 -12
  149. package/skills/opendevbrowser-best-practices/artifacts/command-channel-reference.md +64 -15
  150. package/skills/opendevbrowser-best-practices/artifacts/provider-workflows.md +4 -0
  151. package/skills/opendevbrowser-best-practices/artifacts/skill-runtime-surface-matrix.md +11 -10
  152. package/skills/opendevbrowser-best-practices/assets/templates/canvas-blocker-checklist.json +28 -22
  153. package/skills/opendevbrowser-best-practices/assets/templates/canvas-generation-plan.v1.json +18 -17
  154. package/skills/opendevbrowser-best-practices/assets/templates/canvas-handshake-example.json +135 -17
  155. package/skills/opendevbrowser-best-practices/assets/templates/skill-runtime-pack-matrix.json +55 -8
  156. package/skills/opendevbrowser-best-practices/assets/templates/surface-audit-checklist.json +18 -4
  157. package/skills/opendevbrowser-best-practices/scripts/odb-workflow.sh +16 -4
  158. package/skills/opendevbrowser-best-practices/scripts/run-robustness-audit.sh +3 -1
  159. package/skills/opendevbrowser-best-practices/scripts/validate-skill-assets.sh +68 -25
  160. package/skills/opendevbrowser-design-agent/SKILL.md +9 -4
  161. package/skills/opendevbrowser-design-agent/artifacts/design-workflows.md +15 -6
  162. package/skills/opendevbrowser-design-agent/assets/templates/canvas-generation-plan.design.v1.json +18 -17
  163. package/skills/opendevbrowser-design-agent/scripts/design-workflow.sh +11 -0
  164. package/skills/opendevbrowser-design-agent/scripts/validate-skill-assets.sh +57 -0
  165. package/dist/chunk-5FZQJRBQ.js.map +0 -1
  166. package/dist/chunk-W4IHGDXV.js.map +0 -1
  167. package/dist/chunk-YBQECXZX.js.map +0 -1
  168. /package/dist/{providers-G36AM3Z2.js.map → providers-3VBLTNAX.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,22 @@ import {
30
31
  resolveExitCode,
31
32
  startDaemon,
32
33
  toCliError
33
- } from "../chunk-W4IHGDXV.js";
34
+ } from "../chunk-LMNFPJRI.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 {
43
44
  cleanupExpiredArtifacts,
44
45
  isChallengeAutomationMode,
45
46
  setDefaultLogSink,
46
47
  stderrSink,
47
48
  summarizePrimaryProviderIssue
48
- } from "../chunk-5FZQJRBQ.js";
49
+ } from "../chunk-C6QUKABT.js";
49
50
  import "../chunk-FUSXMW3G.js";
50
51
 
51
52
  // src/cli/args.ts
@@ -245,25 +246,18 @@ function detectOutputFormat(argv) {
245
246
  }
246
247
  }
247
248
 
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
249
  // src/cli/help.ts
261
250
  var LABEL_WIDTH = 42;
262
251
  var DETAIL_LABEL_WIDTH = 9;
263
252
  var COMMAND_SET = new Set(CLI_COMMANDS);
264
253
  var FLAG_SET = new Set(VALID_FLAGS);
265
254
  var TOOL_COUNT = TOOL_SURFACE_ENTRIES.length;
255
+ var CLI_EQUIVALENT_SET = new Set(
256
+ TOOL_SURFACE_ENTRIES.flatMap((entry) => entry.cliEquivalent ? [entry.cliEquivalent] : [])
257
+ );
266
258
  var formatFlags = (flags) => flags.length > 0 ? flags.join(", ") : "none";
259
+ var getCliOnlyCommands = () => CLI_COMMANDS.filter((command) => !CLI_EQUIVALENT_SET.has(command));
260
+ var getToolOnlyHelperNames = () => TOOL_SURFACE_ENTRIES.filter((entry) => !entry.cliEquivalent).map((entry) => entry.name);
267
261
  var HELP_COMMAND_GROUPS = PUBLIC_CLI_COMMAND_GROUPS.map((group) => ({
268
262
  title: group.title,
269
263
  summary: group.summary,
@@ -330,7 +324,7 @@ var HELP_FLAG_GROUPS = [
330
324
  title: "Navigation / Interaction / Diagnostics Flags",
331
325
  summary: "Command-specific flags for page actions, reads, and diagnostics.",
332
326
  flags: [
333
- { flag: "--url", description: "Target URL for navigation, connect, or workflow commands.", example: "opendevbrowser goto --session-id s1 --url https://example.com" },
327
+ { 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
328
  { flag: "--wait-until", description: "Navigation wait strategy such as load or domcontentloaded." },
335
329
  { flag: "--timeout-ms", description: "Operation timeout in milliseconds.", example: "opendevbrowser canvas --timeout-ms 120000 --command canvas.session.open ..." },
336
330
  { flag: "--ref", description: "Snapshot ref id for element-targeted commands.", example: "opendevbrowser click --session-id s1 --ref r12" },
@@ -409,6 +403,9 @@ var HELP_FLAG_GROUPS = [
409
403
  { flag: "--budget", description: "Budget filter for shopping workflows." },
410
404
  { flag: "--region", description: "Region or country hint for provider selection. Treat it as advisory unless output metadata reports `region_authoritative=true`." },
411
405
  { flag: "--sort", description: "Sort mode for shopping results." },
406
+ { flag: "--brief", description: "Inspiredesign brief describing the target design direction." },
407
+ { flag: "--capture-mode", description: "Inspiredesign capture mode: off (default) or deep." },
408
+ { flag: "--include-prototype-guidance", description: "Include inspiredesign prototype guidance in workflow output." },
412
409
  { flag: "--product-url", description: "Target product URL for product-video workflows." },
413
410
  { flag: "--product-name", description: "Product name override for product-video workflows." },
414
411
  { flag: "--provider-hint", description: "Provider hint override for product workflows." },
@@ -438,7 +435,7 @@ var HELP_CAPABILITY_ENTRIES = [
438
435
  },
439
436
  {
440
437
  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.",
438
+ 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
439
  details: [
443
440
  {
444
441
  label: "cli:",
@@ -499,6 +496,14 @@ var HELP_ONBOARDING_ENTRIES = [
499
496
  description: "After guidance, verify a minimal managed happy path before widening into multi-step automation.",
500
497
  details: [{ label: "cli:", value: onboarding_metadata_default.quickStartCommands.happyPath }]
501
498
  },
499
+ {
500
+ label: "surface_split",
501
+ description: "Use the existing public-surface split when a workflow or helper only exists on one side of the CLI or tool surface.",
502
+ details: [
503
+ { label: "cli-only:", value: getCliOnlyCommands().join(", ") },
504
+ { label: "tool-only:", value: getToolOnlyHelperNames().join(", ") }
505
+ ]
506
+ },
502
507
  {
503
508
  label: "docs",
504
509
  description: "Use the first-run checklist and canonical skill runbook for proof and deeper operating details.",
@@ -519,6 +524,7 @@ var HELP_REFERENCE_ENTRIES = [
519
524
  { label: "docs/CLI.md", description: "Detailed CLI guide and release-gate runbooks." },
520
525
  { label: onboarding_metadata_default.referencePaths.onboardingDoc, description: "First-run checklist for help-led onboarding and happy-path proof." },
521
526
  { label: onboarding_metadata_default.referencePaths.skillDoc, description: "Canonical bundled best-practices runbook and quick-start guidance." },
527
+ { label: "docs/WORKFLOW_SURFACE_MAP.md", description: "Code-derived workflow and validation inventory, including CLI-only and tool-only surface splits." },
522
528
  { label: "docs/SURFACE_REFERENCE.md", description: "Canonical CLI, tool, and relay channel inventory." },
523
529
  { label: "opendevbrowser --help", description: "Primary full help invocation for quick discovery." },
524
530
  { label: "opendevbrowser help", description: "Alias that prints the same full help inventory." }
@@ -532,14 +538,7 @@ function formatRows(rows) {
532
538
  return lines.join("\n");
533
539
  }).join("\n");
534
540
  }
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) {
541
+ function assertCommandCoverage() {
543
542
  const seen = /* @__PURE__ */ new Set();
544
543
  for (const group of HELP_COMMAND_GROUPS) {
545
544
  for (const command of group.commands) {
@@ -547,13 +546,10 @@ function assertCommandCoverage(commandDescriptions) {
547
546
  if (!COMMAND_SET.has(command)) {
548
547
  throw new Error(`Help references unknown CLI command: ${command}`);
549
548
  }
550
- if (!commandDescriptions.has(command)) {
551
- throw new Error(`Help references unregistered CLI command: ${command}`);
552
- }
553
549
  if (seen.has(command)) {
554
550
  throw new Error(`Help command appears multiple times: ${command}`);
555
551
  }
556
- if (!detail || !detail.usage.trim()) {
552
+ if (!detail || !detail.description.trim() || !detail.usage.trim()) {
557
553
  throw new Error(`Missing command help metadata: ${command}`);
558
554
  }
559
555
  for (const flag of detail.flags) {
@@ -608,13 +604,13 @@ function assertToolCoverage() {
608
604
  throw new Error(`Help tool inventory must list ${TOOL_COUNT} tools; got ${HELP_TOOL_ENTRIES.length}`);
609
605
  }
610
606
  }
611
- function formatCommandGroups(commandDescriptions) {
607
+ function formatCommandGroups() {
612
608
  return HELP_COMMAND_GROUPS.map((group) => {
613
609
  const rows = group.commands.map((command) => {
614
610
  const detail = COMMAND_HELP_DETAILS[command];
615
611
  return {
616
612
  label: command,
617
- description: commandDescriptions.get(command) ?? "Missing command description.",
613
+ description: detail.description,
618
614
  details: [
619
615
  { label: "usage:", value: detail.usage },
620
616
  { label: "flags:", value: formatFlags(detail.flags) }
@@ -656,8 +652,7 @@ function formatReferenceEntries() {
656
652
  })));
657
653
  }
658
654
  function getHelpText() {
659
- const commandDescriptions = getCommandDescriptions();
660
- assertCommandCoverage(commandDescriptions);
655
+ assertCommandCoverage();
661
656
  assertFlagCoverage();
662
657
  assertToolCoverage();
663
658
  return [
@@ -675,7 +670,7 @@ function getHelpText() {
675
670
  formatOnboardingEntries(),
676
671
  "",
677
672
  `Command Inventory (all ${CLI_COMMANDS.length} commands):`,
678
- formatCommandGroups(commandDescriptions),
673
+ formatCommandGroups(),
679
674
  "",
680
675
  "Flag Inventory (all supported flags):",
681
676
  formatFlagGroups(),
@@ -688,6 +683,15 @@ function getHelpText() {
688
683
  ].join("\n");
689
684
  }
690
685
 
686
+ // src/cli/commands/registry.ts
687
+ var registry = /* @__PURE__ */ new Map();
688
+ function registerCommand(definition) {
689
+ registry.set(definition.name, definition);
690
+ }
691
+ function getCommand(name) {
692
+ return registry.get(name);
693
+ }
694
+
691
695
  // src/cli/installers/global.ts
692
696
  import * as fs3 from "fs";
693
697
 
@@ -964,10 +968,10 @@ function getCodexHomeDir() {
964
968
  return process.env.CODEX_HOME || path3.join(os3.homedir(), ".codex");
965
969
  }
966
970
  function getClaudeCodeHomeDir() {
967
- return process.env.CLAUDECODE_HOME || process.env.CLAUDE_HOME || path3.join(os3.homedir(), ".claude");
971
+ return process.env.CLAUDECODE_HOME || path3.join(os3.homedir(), ".claude");
968
972
  }
969
973
  function getAmpHomeDir() {
970
- return process.env.AMPCLI_HOME || process.env.AMP_CLI_HOME || process.env.AMP_HOME || path3.join(os3.homedir(), ".amp");
974
+ return process.env.AMP_CLI_HOME || path3.join(os3.homedir(), ".amp");
971
975
  }
972
976
  function dedupeTargets(targets) {
973
977
  const deduped = /* @__PURE__ */ new Map();
@@ -991,9 +995,7 @@ function getGlobalSkillTargets() {
991
995
  { agent: "opencode", dir: getGlobalSkillDir() },
992
996
  { agent: "codex", dir: path3.join(getCodexHomeDir(), SKILLS_DIR_NAME) },
993
997
  { agent: "claudecode", dir: claudeSkillsDir },
994
- { agent: "claude", dir: claudeSkillsDir },
995
- { agent: "ampcli", dir: ampSkillsDir },
996
- { agent: "amp", dir: ampSkillsDir }
998
+ { agent: "ampcli", dir: ampSkillsDir }
997
999
  ]);
998
1000
  }
999
1001
  function getLocalSkillTargets() {
@@ -1003,9 +1005,7 @@ function getLocalSkillTargets() {
1003
1005
  { agent: "opencode", dir: getLocalSkillDir() },
1004
1006
  { agent: "codex", dir: path3.join(process.cwd(), ".codex", SKILLS_DIR_NAME) },
1005
1007
  { agent: "claudecode", dir: localClaudeSkillsDir },
1006
- { agent: "claude", dir: localClaudeSkillsDir },
1007
- { agent: "ampcli", dir: localAmpSkillsDir },
1008
- { agent: "amp", dir: localAmpSkillsDir }
1008
+ { agent: "ampcli", dir: localAmpSkillsDir }
1009
1009
  ]);
1010
1010
  }
1011
1011
 
@@ -1511,6 +1511,29 @@ function parseStringArrayFlag(rawArgs, flag) {
1511
1511
  }
1512
1512
  return items;
1513
1513
  }
1514
+ function parseRepeatedStringFlag(rawArgs, flag) {
1515
+ const values = [];
1516
+ for (let index = 0; index < rawArgs.length; index += 1) {
1517
+ const arg = rawArgs[index];
1518
+ if (arg === flag) {
1519
+ const value = rawArgs[index + 1];
1520
+ if (!value) {
1521
+ throw createUsageError(`Missing value for ${flag}`);
1522
+ }
1523
+ values.push(value);
1524
+ index += 1;
1525
+ continue;
1526
+ }
1527
+ if (arg?.startsWith(`${flag}=`)) {
1528
+ const value = arg.split("=", 2)[1];
1529
+ if (!value) {
1530
+ throw createUsageError(`Missing value for ${flag}`);
1531
+ }
1532
+ values.push(value);
1533
+ }
1534
+ }
1535
+ return values.length > 0 ? values : void 0;
1536
+ }
1514
1537
 
1515
1538
  // src/cli/commands/native.ts
1516
1539
  import * as fs8 from "fs";
@@ -1919,6 +1942,32 @@ async function resolveExistingDaemon(port, tokens) {
1919
1942
  }
1920
1943
  return null;
1921
1944
  }
1945
+ function isPositivePid(value) {
1946
+ return typeof value === "number" && Number.isInteger(value) && value > 0;
1947
+ }
1948
+ function rememberStalePid(staleDaemonPids, pid) {
1949
+ if (isPositivePid(pid)) {
1950
+ staleDaemonPids.add(pid);
1951
+ }
1952
+ }
1953
+ async function stopDaemonOnPort(port, token) {
1954
+ try {
1955
+ const response = await fetchWithTimeout(`http://127.0.0.1:${port}/stop`, {
1956
+ method: "POST",
1957
+ headers: { Authorization: `Bearer ${token}` }
1958
+ });
1959
+ return response.ok;
1960
+ } catch {
1961
+ return false;
1962
+ }
1963
+ }
1964
+ async function stopStaleDaemon(port, daemon, staleDaemonPids) {
1965
+ rememberStalePid(staleDaemonPids, daemon.status.pid);
1966
+ const stopped = await stopDaemonOnPort(port, daemon.token);
1967
+ if (!stopped && isPositivePid(daemon.status.pid)) {
1968
+ terminateProcess(daemon.status.pid);
1969
+ }
1970
+ }
1922
1971
  function parseServeArgs(rawArgs) {
1923
1972
  const parsed = { stop: false };
1924
1973
  for (let i = 0; i < rawArgs.length; i += 1) {
@@ -2081,27 +2130,34 @@ async function runServe(args) {
2081
2130
  const metadata = readDaemonMetadata();
2082
2131
  const metadataToken = metadata?.port === requestedPort ? metadata.token : void 0;
2083
2132
  const tokenCandidates = resolveTokenCandidates(serveArgs.token, metadataToken, config.daemonToken);
2133
+ const currentFingerprint = getCurrentDaemonFingerprint();
2084
2134
  const existingDaemon = await resolveExistingDaemon(requestedPort, tokenCandidates);
2085
2135
  const staleDaemonPids = new Set(cleanupCompetingServeProcesses(existingDaemon?.status.pid));
2086
2136
  const staleCleared = () => staleDaemonPids.size;
2137
+ let replacedStaleFingerprint = false;
2087
2138
  if (existingDaemon) {
2088
- const relayPort = existingDaemon.status.relay.port ?? config.relayPort;
2089
- const clearedCount2 = staleCleared();
2090
- const staleNote2 = clearedCount2 > 0 ? `
2139
+ const fingerprintMatches = existingDaemon.status.fingerprint === currentFingerprint;
2140
+ if (fingerprintMatches) {
2141
+ const relayPort = existingDaemon.status.relay.port ?? config.relayPort;
2142
+ const clearedCount2 = staleCleared();
2143
+ const staleNote2 = clearedCount2 > 0 ? `
2091
2144
  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
- };
2145
+ return {
2146
+ success: true,
2147
+ message: `Daemon already running on 127.0.0.1:${requestedPort} (pid=${existingDaemon.status.pid}, relay ${relayPort}).${staleNote2}`,
2148
+ data: {
2149
+ port: requestedPort,
2150
+ pid: existingDaemon.status.pid,
2151
+ relayPort,
2152
+ alreadyRunning: true,
2153
+ staleDaemonsCleared: clearedCount2,
2154
+ relay: existingDaemon.status.relay
2155
+ },
2156
+ exitCode: null
2157
+ };
2158
+ }
2159
+ await stopStaleDaemon(requestedPort, existingDaemon, staleDaemonPids);
2160
+ replacedStaleFingerprint = true;
2105
2161
  }
2106
2162
  let nativeStatus = getNativeStatusSnapshot();
2107
2163
  let nativeMessage = null;
@@ -2144,23 +2200,31 @@ Cleared ${clearedCount2} stale daemon process${clearedCount2 === 1 ? "" : "es"}.
2144
2200
  }
2145
2201
  const runningDaemon = await resolveExistingDaemon(requestedPort, tokenCandidates);
2146
2202
  if (runningDaemon) {
2147
- const relayPort = runningDaemon.status.relay.port ?? config.relayPort;
2148
- const clearedCount2 = staleCleared();
2149
- const staleNote2 = clearedCount2 > 0 ? `
2203
+ const fingerprintMatches = runningDaemon.status.fingerprint === currentFingerprint;
2204
+ if (fingerprintMatches) {
2205
+ const relayPort = runningDaemon.status.relay.port ?? config.relayPort;
2206
+ const clearedCount2 = staleCleared();
2207
+ const staleNote2 = clearedCount2 > 0 ? `
2150
2208
  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
- };
2209
+ return {
2210
+ success: true,
2211
+ message: `Daemon already running on 127.0.0.1:${requestedPort} (pid=${runningDaemon.status.pid}, relay ${relayPort}).${staleNote2}`,
2212
+ data: {
2213
+ port: requestedPort,
2214
+ pid: runningDaemon.status.pid,
2215
+ relayPort,
2216
+ alreadyRunning: true,
2217
+ staleDaemonsCleared: clearedCount2,
2218
+ relay: runningDaemon.status.relay
2219
+ },
2220
+ exitCode: null
2221
+ };
2222
+ }
2223
+ await stopStaleDaemon(requestedPort, runningDaemon, staleDaemonPids);
2224
+ replacedStaleFingerprint = true;
2225
+ if (attempt === 0) {
2226
+ continue;
2227
+ }
2164
2228
  }
2165
2229
  if (attempt === 0) {
2166
2230
  let clearedNewPid = false;
@@ -2199,8 +2263,9 @@ Cleared ${clearedCount2} stale daemon process${clearedCount2 === 1 ? "" : "es"}.
2199
2263
  const clearedCount = staleCleared();
2200
2264
  const staleNote = clearedCount > 0 ? `
2201
2265
  Cleared ${clearedCount} stale daemon process${clearedCount === 1 ? "" : "es"}.` : "";
2266
+ const fingerprintNote = replacedStaleFingerprint ? "\nReplaced stale daemon fingerprint." : "";
2202
2267
  const message = nativeMessage ? `${baseMessage}
2203
- ${nativeMessage}${staleNote}` : `${baseMessage}${staleNote}`;
2268
+ ${nativeMessage}${fingerprintNote}${staleNote}` : `${baseMessage}${fingerprintNote}${staleNote}`;
2204
2269
  return {
2205
2270
  success: true,
2206
2271
  message,
@@ -3600,94 +3665,138 @@ async function runSessionDisconnect(args) {
3600
3665
  return { success: true, message: `Session disconnected: ${sessionId}` };
3601
3666
  }
3602
3667
 
3603
- // src/cli/commands/session/inspector.ts
3668
+ // src/cli/utils/workflow-message.ts
3669
+ var asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
3670
+ var readNonEmptyString = (value) => typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
3671
+ var readMeta = (data) => {
3672
+ return asRecord(asRecord(data)?.meta);
3673
+ };
3674
+ var readPrimaryConstraint = (data) => {
3675
+ const meta = readMeta(data);
3676
+ if (!meta) return null;
3677
+ return asRecord(meta.primaryConstraint);
3678
+ };
3679
+ var readPrimarySummary = (data) => {
3680
+ const meta = readMeta(data);
3681
+ return readNonEmptyString(meta?.primaryConstraintSummary);
3682
+ };
3683
+ var readPrimaryNextStep = (data) => {
3684
+ const constraint = readPrimaryConstraint(data);
3685
+ if (!constraint) return null;
3686
+ const guidance = asRecord(constraint.guidance);
3687
+ if (!guidance) return null;
3688
+ const commands = guidance.recommendedNextCommands;
3689
+ if (!Array.isArray(commands)) return null;
3690
+ const nextStep = commands.find((entry) => typeof entry === "string" && entry.trim().length > 0);
3691
+ return nextStep?.trim() ?? null;
3692
+ };
3693
+ var readFailures = (data) => {
3694
+ const meta = readMeta(data);
3695
+ if (!meta) return [];
3696
+ const failures = meta.failures;
3697
+ return Array.isArray(failures) ? failures.filter((entry) => Boolean(entry) && typeof entry === "object") : [];
3698
+ };
3699
+ var readSuggestedSteps = (data) => {
3700
+ const steps = asRecord(data)?.suggestedSteps;
3701
+ return Array.isArray(steps) ? steps.flatMap((step) => {
3702
+ const record = asRecord(step);
3703
+ return record ? [record] : [];
3704
+ }) : [];
3705
+ };
3706
+ var buildNextStepMessage = (message, nextStep) => {
3707
+ return nextStep ? `${message} Next step: ${nextStep}` : message;
3708
+ };
3709
+ var readSuggestedNextAction = (data) => {
3710
+ const record = asRecord(data);
3711
+ if (!record) return null;
3712
+ return readNonEmptyString(record.suggestedNextAction) ?? readNonEmptyString(asRecord(record.sessionInspector)?.suggestedNextAction);
3713
+ };
3714
+ var readSuggestedStepReason = (data) => {
3715
+ let current = asRecord(data);
3716
+ while (current) {
3717
+ const [firstStep] = readSuggestedSteps(current);
3718
+ if (firstStep) {
3719
+ return readNonEmptyString(firstStep.reason);
3720
+ }
3721
+ current = asRecord(current.challengePlan);
3722
+ }
3723
+ return null;
3724
+ };
3725
+ var buildWorkflowCompletionMessage = (workflowLabel, data) => {
3726
+ const explicitSummary = readPrimarySummary(data);
3727
+ if (explicitSummary) {
3728
+ return buildNextStepMessage(
3729
+ `${workflowLabel} completed with provider follow-up required: ${explicitSummary}`,
3730
+ readPrimaryNextStep(data)
3731
+ );
3732
+ }
3733
+ const inferred = summarizePrimaryProviderIssue(readFailures(data));
3734
+ if (inferred) {
3735
+ return buildNextStepMessage(
3736
+ `${workflowLabel} completed with provider follow-up required: ${inferred.summary}`,
3737
+ inferred.guidance?.recommendedNextCommands[0] ?? null
3738
+ );
3739
+ }
3740
+ return `${workflowLabel} completed.`;
3741
+ };
3742
+
3743
+ // src/cli/commands/session/inspector-shared.ts
3604
3744
  function parseSessionInspectorArgs(rawArgs) {
3605
3745
  const parsed = {};
3606
3746
  for (let index = 0; index < rawArgs.length; index += 1) {
3607
3747
  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
3748
  if (arg === "--include-urls") {
3620
3749
  parsed.includeUrls = true;
3621
3750
  continue;
3622
3751
  }
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;
3752
+ if (arg === "--session-id" || arg?.startsWith("--session-id=")) {
3753
+ parsed.sessionId = readStringFlag(rawArgs, index, "--session-id");
3754
+ index += stepForValue(arg);
3628
3755
  continue;
3629
3756
  }
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 });
3757
+ if (arg === "--since-console-seq" || arg?.startsWith("--since-console-seq=")) {
3758
+ parsed.sinceConsoleSeq = readNumberFlag(rawArgs, index, "--since-console-seq", { min: 0 });
3759
+ index += stepForValue(arg);
3634
3760
  continue;
3635
3761
  }
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;
3762
+ if (arg === "--since-network-seq" || arg?.startsWith("--since-network-seq=")) {
3763
+ parsed.sinceNetworkSeq = readNumberFlag(rawArgs, index, "--since-network-seq", { min: 0 });
3764
+ index += stepForValue(arg);
3641
3765
  continue;
3642
3766
  }
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 });
3767
+ if (arg === "--since-exception-seq" || arg?.startsWith("--since-exception-seq=")) {
3768
+ parsed.sinceExceptionSeq = readNumberFlag(rawArgs, index, "--since-exception-seq", { min: 0 });
3769
+ index += stepForValue(arg);
3647
3770
  continue;
3648
3771
  }
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;
3772
+ if (arg === "--max" || arg?.startsWith("--max=")) {
3773
+ parsed.max = readNumberFlag(rawArgs, index, "--max", { min: 1 });
3774
+ index += stepForValue(arg);
3654
3775
  continue;
3655
3776
  }
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;
3777
+ if (arg === "--request-id" || arg?.startsWith("--request-id=")) {
3778
+ parsed.requestId = readStringFlag(rawArgs, index, "--request-id");
3779
+ index += stepForValue(arg);
3687
3780
  }
3688
3781
  }
3689
3782
  return parsed;
3690
3783
  }
3784
+ function stepForValue(flag) {
3785
+ return flag.includes("=") ? 0 : 1;
3786
+ }
3787
+ function readNumberFlag(rawArgs, index, flag, options) {
3788
+ return parseNumberFlag(readStringFlag(rawArgs, index, flag), flag, options);
3789
+ }
3790
+ function readStringFlag(rawArgs, index, flag) {
3791
+ const arg = rawArgs[index];
3792
+ const value = arg?.includes("=") ? arg.split("=", 2)[1] : rawArgs[index + 1];
3793
+ if (!value) {
3794
+ throw createUsageError(`Missing value for ${flag}`);
3795
+ }
3796
+ return value;
3797
+ }
3798
+
3799
+ // src/cli/commands/session/inspector.ts
3691
3800
  async function runSessionInspector(args) {
3692
3801
  const parsed = parseSessionInspectorArgs(args.rawArgs);
3693
3802
  if (!parsed.sessionId) {
@@ -3704,7 +3813,115 @@ async function runSessionInspector(args) {
3704
3813
  });
3705
3814
  return {
3706
3815
  success: true,
3707
- message: "Session inspector snapshot captured.",
3816
+ message: buildNextStepMessage(
3817
+ "Session inspector snapshot captured.",
3818
+ readSuggestedNextAction(result)
3819
+ ),
3820
+ data: result
3821
+ };
3822
+ }
3823
+
3824
+ // src/cli/transport-timeouts.ts
3825
+ var DEFAULT_CLICK_TRANSPORT_TIMEOUT_MS = 6e4;
3826
+ var DEFAULT_DIALOG_TRANSPORT_TIMEOUT_MS = 3e4;
3827
+ var DEFAULT_TARGET_CREATION_TRANSPORT_TIMEOUT_MS = 3e4;
3828
+ var DEFAULT_SNAPSHOT_TRANSPORT_TIMEOUT_MS = 3e4;
3829
+ var DEFAULT_REVIEW_TRANSPORT_TIMEOUT_MS = 3e4;
3830
+ var DEFAULT_SCREENSHOT_TRANSPORT_TIMEOUT_MS = 3e4;
3831
+ var DEFAULT_WORKFLOW_TRANSPORT_TIMEOUT_MS = 12e4;
3832
+
3833
+ // src/cli/commands/challenge-automation-mode.ts
3834
+ function parseOptionalChallengeAutomationMode(rawArgs) {
3835
+ const value = parseOptionalStringFlag(rawArgs, "--challenge-automation-mode");
3836
+ if (typeof value === "undefined") {
3837
+ return void 0;
3838
+ }
3839
+ if (!isChallengeAutomationMode(value)) {
3840
+ throw createUsageError(`Invalid --challenge-automation-mode: ${value}`);
3841
+ }
3842
+ return value;
3843
+ }
3844
+
3845
+ // src/cli/commands/nav/review-shared.ts
3846
+ function parseOptionalNumberFlag(rawArgs, flag, options) {
3847
+ const value = parseOptionalStringFlag(rawArgs, flag);
3848
+ return typeof value === "string" ? parseNumberFlag(value, flag, options) : void 0;
3849
+ }
3850
+ function parseReviewCommandArgs(rawArgs) {
3851
+ return {
3852
+ sessionId: parseOptionalStringFlag(rawArgs, "--session-id"),
3853
+ targetId: parseOptionalStringFlag(rawArgs, "--target-id"),
3854
+ reason: parseOptionalStringFlag(rawArgs, "--reason"),
3855
+ maxChars: parseOptionalNumberFlag(rawArgs, "--max-chars", { min: 1 }),
3856
+ cursor: parseOptionalStringFlag(rawArgs, "--cursor"),
3857
+ timeoutMs: parseOptionalNumberFlag(rawArgs, "--timeout-ms", { min: 1 })
3858
+ };
3859
+ }
3860
+
3861
+ // src/cli/commands/session/inspector-audit.ts
3862
+ function parseOptionalTimeoutMs(rawArgs) {
3863
+ const value = parseOptionalStringFlag(rawArgs, "--timeout-ms");
3864
+ return typeof value === "string" ? parseNumberFlag(value, "--timeout-ms", { min: 1 }) : void 0;
3865
+ }
3866
+ async function runSessionInspectorAudit(args) {
3867
+ const reviewArgs = parseReviewCommandArgs(args.rawArgs);
3868
+ const inspectorArgs = parseSessionInspectorArgs(args.rawArgs);
3869
+ const challengeAutomationMode = parseOptionalChallengeAutomationMode(args.rawArgs);
3870
+ const timeoutMs = parseOptionalTimeoutMs(args.rawArgs);
3871
+ const sessionId = reviewArgs.sessionId ?? inspectorArgs.sessionId;
3872
+ if (!sessionId) {
3873
+ throw createUsageError("Missing --session-id");
3874
+ }
3875
+ const result = await callDaemon("session.inspectAudit", {
3876
+ sessionId,
3877
+ ...typeof reviewArgs.targetId === "string" ? { targetId: reviewArgs.targetId } : {},
3878
+ ...typeof reviewArgs.reason === "string" ? { reason: reviewArgs.reason } : {},
3879
+ ...typeof reviewArgs.maxChars === "number" ? { maxChars: reviewArgs.maxChars } : {},
3880
+ ...typeof reviewArgs.cursor === "string" ? { cursor: reviewArgs.cursor } : {},
3881
+ ...typeof inspectorArgs.includeUrls === "boolean" ? { includeUrls: inspectorArgs.includeUrls } : {},
3882
+ ...typeof inspectorArgs.sinceConsoleSeq === "number" ? { sinceConsoleSeq: inspectorArgs.sinceConsoleSeq } : {},
3883
+ ...typeof inspectorArgs.sinceNetworkSeq === "number" ? { sinceNetworkSeq: inspectorArgs.sinceNetworkSeq } : {},
3884
+ ...typeof inspectorArgs.sinceExceptionSeq === "number" ? { sinceExceptionSeq: inspectorArgs.sinceExceptionSeq } : {},
3885
+ ...typeof inspectorArgs.max === "number" ? { max: inspectorArgs.max } : {},
3886
+ ...typeof inspectorArgs.requestId === "string" ? { requestId: inspectorArgs.requestId } : {},
3887
+ ...challengeAutomationMode ? { challengeAutomationMode } : {}
3888
+ }, {
3889
+ timeoutMs: timeoutMs ?? DEFAULT_REVIEW_TRANSPORT_TIMEOUT_MS
3890
+ });
3891
+ const nextStep = readSuggestedNextAction(result) ?? readSuggestedStepReason(result);
3892
+ return {
3893
+ success: true,
3894
+ message: buildNextStepMessage("Correlated audit bundle captured.", nextStep),
3895
+ data: result
3896
+ };
3897
+ }
3898
+
3899
+ // src/cli/commands/session/inspector-plan.ts
3900
+ function parseOptionalTimeoutMs2(rawArgs) {
3901
+ const value = parseOptionalStringFlag(rawArgs, "--timeout-ms");
3902
+ return typeof value === "string" ? parseNumberFlag(value, "--timeout-ms", { min: 1 }) : void 0;
3903
+ }
3904
+ async function runSessionInspectorPlan(args) {
3905
+ const sessionId = parseOptionalStringFlag(args.rawArgs, "--session-id");
3906
+ const targetId = parseOptionalStringFlag(args.rawArgs, "--target-id");
3907
+ const challengeAutomationMode = parseOptionalChallengeAutomationMode(args.rawArgs);
3908
+ const timeoutMs = parseOptionalTimeoutMs2(args.rawArgs);
3909
+ if (!sessionId) {
3910
+ throw createUsageError("Missing --session-id");
3911
+ }
3912
+ const result = await callDaemon("session.inspectPlan", {
3913
+ sessionId,
3914
+ ...typeof targetId === "string" ? { targetId } : {},
3915
+ ...challengeAutomationMode ? { challengeAutomationMode } : {}
3916
+ }, {
3917
+ timeoutMs: timeoutMs ?? DEFAULT_REVIEW_TRANSPORT_TIMEOUT_MS
3918
+ });
3919
+ return {
3920
+ success: true,
3921
+ message: buildNextStepMessage(
3922
+ "Challenge inspect plan captured.",
3923
+ readSuggestedStepReason(result)
3924
+ ),
3708
3925
  data: result
3709
3926
  };
3710
3927
  }
@@ -3811,6 +4028,30 @@ async function runStatus(args) {
3811
4028
  };
3812
4029
  }
3813
4030
 
4031
+ // src/cli/commands/status-capabilities.ts
4032
+ function parseOptionalTimeoutMs3(rawArgs) {
4033
+ const value = parseOptionalStringFlag(rawArgs, "--timeout-ms");
4034
+ return typeof value === "string" ? parseNumberFlag(value, "--timeout-ms", { min: 1 }) : void 0;
4035
+ }
4036
+ async function runStatusCapabilities(args) {
4037
+ const sessionId = parseOptionalStringFlag(args.rawArgs, "--session-id");
4038
+ const targetId = parseOptionalStringFlag(args.rawArgs, "--target-id");
4039
+ const challengeAutomationMode = parseOptionalChallengeAutomationMode(args.rawArgs);
4040
+ const timeoutMs = parseOptionalTimeoutMs3(args.rawArgs);
4041
+ const result = await callDaemon("status.capabilities", {
4042
+ ...typeof sessionId === "string" ? { sessionId } : {},
4043
+ ...typeof targetId === "string" ? { targetId } : {},
4044
+ ...challengeAutomationMode ? { challengeAutomationMode } : {}
4045
+ }, {
4046
+ timeoutMs: timeoutMs ?? DEFAULT_REVIEW_TRANSPORT_TIMEOUT_MS
4047
+ });
4048
+ return {
4049
+ success: true,
4050
+ message: "Capability discovery captured.",
4051
+ data: result
4052
+ };
4053
+ }
4054
+
3814
4055
  // src/cli/commands/nav/goto.ts
3815
4056
  function parseGotoArgs(rawArgs) {
3816
4057
  const parsed = {};
@@ -3960,15 +4201,6 @@ async function runWait(args) {
3960
4201
  return { success: true, message: "Wait complete.", data: result };
3961
4202
  }
3962
4203
 
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
4204
  // src/cli/commands/nav/snapshot.ts
3973
4205
  function parseSnapshotArgs(rawArgs) {
3974
4206
  const parsed = {};
@@ -4051,61 +4283,8 @@ async function runSnapshot(args) {
4051
4283
  }
4052
4284
 
4053
4285
  // 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
4286
  async function runReview(args) {
4107
- const { sessionId, maxChars, cursor, timeoutMs } = parseReviewArgs(args.rawArgs);
4108
- const targetId = parseOptionalStringFlag(args.rawArgs, "--target-id");
4287
+ const { sessionId, targetId, maxChars, cursor, timeoutMs } = parseReviewCommandArgs(args.rawArgs);
4109
4288
  if (!sessionId) throw createUsageError("Missing --session-id");
4110
4289
  const payload = {
4111
4290
  sessionId,
@@ -4119,6 +4298,28 @@ async function runReview(args) {
4119
4298
  return { success: true, message: "Review captured.", data: result };
4120
4299
  }
4121
4300
 
4301
+ // src/cli/commands/nav/review-desktop.ts
4302
+ async function runReviewDesktop(args) {
4303
+ const { sessionId, targetId, reason, maxChars, cursor, timeoutMs } = parseReviewCommandArgs(args.rawArgs);
4304
+ if (!sessionId) {
4305
+ throw createUsageError("Missing --session-id");
4306
+ }
4307
+ const result = await callDaemon("nav.reviewDesktop", {
4308
+ sessionId,
4309
+ ...typeof targetId === "string" ? { targetId } : {},
4310
+ ...typeof reason === "string" ? { reason } : {},
4311
+ ...typeof maxChars === "number" ? { maxChars } : {},
4312
+ ...typeof cursor === "string" ? { cursor } : {}
4313
+ }, {
4314
+ timeoutMs: timeoutMs ?? DEFAULT_REVIEW_TRANSPORT_TIMEOUT_MS
4315
+ });
4316
+ return {
4317
+ success: true,
4318
+ message: "Desktop-assisted review captured.",
4319
+ data: result
4320
+ };
4321
+ }
4322
+
4122
4323
  // src/cli/commands/annotate.ts
4123
4324
  var requireValue2 = (value, flag) => {
4124
4325
  if (!value) throw createUsageError(`Missing value for ${flag}`);
@@ -6660,6 +6861,13 @@ async function runCookieList(args) {
6660
6861
  }
6661
6862
 
6662
6863
  // src/cli/commands/macro-resolve.ts
6864
+ var MACRO_TRANSPORT_TIMEOUT_BUFFER_MS = 6e4;
6865
+ var deriveMacroTransportTimeoutMs = (timeoutMs) => {
6866
+ return Math.max(
6867
+ DEFAULT_WORKFLOW_TRANSPORT_TIMEOUT_MS,
6868
+ timeoutMs + MACRO_TRANSPORT_TIMEOUT_BUFFER_MS
6869
+ );
6870
+ };
6663
6871
  var requireValue7 = (value, flag) => {
6664
6872
  if (!value) {
6665
6873
  throw createUsageError(`Missing value for ${flag}`);
@@ -6739,7 +6947,9 @@ async function runMacroResolve(args) {
6739
6947
  ...typeof parsed.timeoutMs === "number" ? { timeoutMs: parsed.timeoutMs } : {},
6740
6948
  ...parsed.challengeAutomationMode ? { challengeAutomationMode: parsed.challengeAutomationMode } : {}
6741
6949
  };
6742
- const result = typeof parsed.timeoutMs === "number" ? await callDaemon("macro.resolve", params, { timeoutMs: parsed.timeoutMs }) : await callDaemon("macro.resolve", params);
6950
+ const result = typeof parsed.timeoutMs === "number" ? await callDaemon("macro.resolve", params, {
6951
+ timeoutMs: deriveMacroTransportTimeoutMs(parsed.timeoutMs)
6952
+ }) : await callDaemon("macro.resolve", params);
6743
6953
  return {
6744
6954
  success: true,
6745
6955
  message: parsed.execute ? "Macro resolved and executed." : "Macro resolved.",
@@ -6747,36 +6957,6 @@ async function runMacroResolve(args) {
6747
6957
  };
6748
6958
  }
6749
6959
 
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
6960
  // src/cli/commands/research.ts
6781
6961
  var SOURCE_VALUES = /* @__PURE__ */ new Set(["web", "community", "social", "shopping"]);
6782
6962
  var SOURCE_SELECTION_VALUES = /* @__PURE__ */ new Set(["auto", "web", "community", "social", "shopping", "all"]);
@@ -7409,10 +7589,177 @@ async function runProductVideoCommand(args) {
7409
7589
  };
7410
7590
  }
7411
7591
 
7592
+ // src/cli/commands/inspiredesign.ts
7593
+ var MODE_VALUES3 = /* @__PURE__ */ new Set(["compact", "json", "md", "context", "path"]);
7594
+ var CAPTURE_MODE_VALUES = /* @__PURE__ */ new Set(["off", "deep"]);
7595
+ var COOKIE_POLICY_VALUES4 = /* @__PURE__ */ new Set(["off", "auto", "required"]);
7596
+ var requireValue11 = (rawArgs, index, flag) => {
7597
+ const value = rawArgs[index + 1];
7598
+ if (!value) {
7599
+ throw createUsageError(`Missing value for ${flag}`);
7600
+ }
7601
+ return value;
7602
+ };
7603
+ var parseInspiredesignRunArgs = (rawArgs) => {
7604
+ const parsed = {
7605
+ brief: parseOptionalStringFlag(rawArgs, "--brief"),
7606
+ urls: parseRepeatedStringFlag(rawArgs, "--url")
7607
+ };
7608
+ for (let index = 0; index < rawArgs.length; index += 1) {
7609
+ const arg = rawArgs[index];
7610
+ if (arg === "--brief" || arg === "--url") {
7611
+ index += 1;
7612
+ continue;
7613
+ }
7614
+ if (arg?.startsWith("--brief=") || arg?.startsWith("--url=")) {
7615
+ continue;
7616
+ }
7617
+ if (arg === "--capture-mode") {
7618
+ const value = requireValue11(rawArgs, index, "--capture-mode").toLowerCase();
7619
+ if (!CAPTURE_MODE_VALUES.has(value)) {
7620
+ throw createUsageError(`Invalid --capture-mode: ${value}`);
7621
+ }
7622
+ parsed.captureMode = value;
7623
+ index += 1;
7624
+ continue;
7625
+ }
7626
+ if (arg?.startsWith("--capture-mode=")) {
7627
+ const value = (arg.split("=", 2)[1] ?? "").toLowerCase();
7628
+ if (!CAPTURE_MODE_VALUES.has(value)) {
7629
+ throw createUsageError(`Invalid --capture-mode: ${value}`);
7630
+ }
7631
+ parsed.captureMode = value;
7632
+ continue;
7633
+ }
7634
+ if (arg === "--include-prototype-guidance") {
7635
+ parsed.includePrototypeGuidance = true;
7636
+ continue;
7637
+ }
7638
+ if (arg?.startsWith("--include-prototype-guidance=")) {
7639
+ parsed.includePrototypeGuidance = parseBooleanFlag(arg.split("=", 2)[1] ?? "", "--include-prototype-guidance");
7640
+ continue;
7641
+ }
7642
+ if (arg === "--mode") {
7643
+ const value = requireValue11(rawArgs, index, "--mode").toLowerCase();
7644
+ if (!MODE_VALUES3.has(value)) {
7645
+ throw createUsageError(`Invalid --mode: ${value}`);
7646
+ }
7647
+ parsed.mode = value;
7648
+ index += 1;
7649
+ continue;
7650
+ }
7651
+ if (arg?.startsWith("--mode=")) {
7652
+ const value = (arg.split("=", 2)[1] ?? "").toLowerCase();
7653
+ if (!MODE_VALUES3.has(value)) {
7654
+ throw createUsageError(`Invalid --mode: ${value}`);
7655
+ }
7656
+ parsed.mode = value;
7657
+ continue;
7658
+ }
7659
+ if (arg === "--timeout-ms") {
7660
+ parsed.timeoutMs = parseNumberFlag(requireValue11(rawArgs, index, "--timeout-ms"), "--timeout-ms", { min: 1 });
7661
+ index += 1;
7662
+ continue;
7663
+ }
7664
+ if (arg?.startsWith("--timeout-ms=")) {
7665
+ parsed.timeoutMs = parseNumberFlag(arg.split("=", 2)[1] ?? "", "--timeout-ms", { min: 1 });
7666
+ continue;
7667
+ }
7668
+ if (arg === "--output-dir") {
7669
+ parsed.outputDir = requireValue11(rawArgs, index, "--output-dir");
7670
+ index += 1;
7671
+ continue;
7672
+ }
7673
+ if (arg?.startsWith("--output-dir=")) {
7674
+ parsed.outputDir = arg.split("=", 2)[1];
7675
+ continue;
7676
+ }
7677
+ if (arg === "--ttl-hours") {
7678
+ parsed.ttlHours = parseNumberFlag(requireValue11(rawArgs, index, "--ttl-hours"), "--ttl-hours", { min: 1, max: 168 });
7679
+ index += 1;
7680
+ continue;
7681
+ }
7682
+ if (arg?.startsWith("--ttl-hours=")) {
7683
+ parsed.ttlHours = parseNumberFlag(arg.split("=", 2)[1] ?? "", "--ttl-hours", { min: 1, max: 168 });
7684
+ continue;
7685
+ }
7686
+ if (arg === "--use-cookies") {
7687
+ parsed.useCookies = true;
7688
+ continue;
7689
+ }
7690
+ if (arg?.startsWith("--use-cookies=")) {
7691
+ parsed.useCookies = parseBooleanFlag(arg.split("=", 2)[1] ?? "", "--use-cookies");
7692
+ continue;
7693
+ }
7694
+ if (arg === "--challenge-automation-mode") {
7695
+ const value = requireValue11(rawArgs, index, "--challenge-automation-mode");
7696
+ if (!isChallengeAutomationMode(value)) {
7697
+ throw createUsageError(`Invalid --challenge-automation-mode: ${value}`);
7698
+ }
7699
+ parsed.challengeAutomationMode = value;
7700
+ index += 1;
7701
+ continue;
7702
+ }
7703
+ if (arg?.startsWith("--challenge-automation-mode=")) {
7704
+ const value = arg.split("=", 2)[1] ?? "";
7705
+ if (!isChallengeAutomationMode(value)) {
7706
+ throw createUsageError(`Invalid --challenge-automation-mode: ${value}`);
7707
+ }
7708
+ parsed.challengeAutomationMode = value;
7709
+ continue;
7710
+ }
7711
+ if (arg === "--cookie-policy-override" || arg === "--cookie-policy") {
7712
+ const value = requireValue11(rawArgs, index, arg).toLowerCase();
7713
+ if (!COOKIE_POLICY_VALUES4.has(value)) {
7714
+ throw createUsageError(`Invalid ${arg}: ${value}`);
7715
+ }
7716
+ parsed.cookiePolicyOverride = value;
7717
+ index += 1;
7718
+ continue;
7719
+ }
7720
+ if (arg?.startsWith("--cookie-policy-override=") || arg?.startsWith("--cookie-policy=")) {
7721
+ const value = (arg.split("=", 2)[1] ?? "").toLowerCase();
7722
+ if (!COOKIE_POLICY_VALUES4.has(value)) {
7723
+ throw createUsageError(`Invalid --cookie-policy-override: ${value}`);
7724
+ }
7725
+ parsed.cookiePolicyOverride = value;
7726
+ }
7727
+ }
7728
+ return parsed;
7729
+ };
7730
+ async function runInspiredesignCommand(args) {
7731
+ const [subcommand, ...rest] = args.rawArgs;
7732
+ if (subcommand !== "run") {
7733
+ throw createUsageError("Usage: opendevbrowser inspiredesign run --brief <value> [--url <url>] [options]");
7734
+ }
7735
+ const parsed = parseInspiredesignRunArgs(rest);
7736
+ if (!parsed.brief?.trim()) {
7737
+ throw createUsageError("Missing --brief");
7738
+ }
7739
+ const data = await callDaemon("inspiredesign.run", {
7740
+ brief: parsed.brief,
7741
+ urls: parsed.urls,
7742
+ captureMode: parsed.captureMode ?? "off",
7743
+ includePrototypeGuidance: parsed.includePrototypeGuidance,
7744
+ mode: parsed.mode ?? "compact",
7745
+ timeoutMs: parsed.timeoutMs ?? DEFAULT_WORKFLOW_TRANSPORT_TIMEOUT_MS,
7746
+ outputDir: parsed.outputDir,
7747
+ ttlHours: parsed.ttlHours,
7748
+ useCookies: parsed.useCookies,
7749
+ challengeAutomationMode: parsed.challengeAutomationMode,
7750
+ cookiePolicyOverride: parsed.cookiePolicyOverride
7751
+ });
7752
+ return {
7753
+ success: true,
7754
+ message: buildWorkflowCompletionMessage("Inspiredesign workflow", data),
7755
+ data
7756
+ };
7757
+ }
7758
+
7412
7759
  // package.json
7413
7760
  var package_default = {
7414
7761
  name: "opendevbrowser",
7415
- version: "0.0.19",
7762
+ version: "0.0.20",
7416
7763
  description: "Browser automation runtime with snapshot-refs-actions, browser replay screencasts, public read-only desktop observation, and browser-scoped computer-use orchestration",
7417
7764
  type: "module",
7418
7765
  main: "dist/index.js",
@@ -7457,10 +7804,10 @@ var package_default = {
7457
7804
  node: ">=18"
7458
7805
  },
7459
7806
  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",
7807
+ 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
7808
  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",
7809
+ lint: 'node scripts/run-package-tool.mjs eslint "src/**/*.ts" "tests/**/*.ts"',
7810
+ typecheck: "node scripts/run-package-tool.mjs tsc --noEmit -p tsconfig.json",
7464
7811
  test: "node scripts/run-vitest-coverage.mjs",
7465
7812
  "test:release-gate": "node scripts/release-gate-test-groups.mjs",
7466
7813
  "test:release-gate:g1": "node scripts/release-gate-test-groups.mjs --group 1",
@@ -7469,7 +7816,7 @@ var package_default = {
7469
7816
  "test:release-gate:g4": "node scripts/release-gate-test-groups.mjs --group 4",
7470
7817
  "test:release-gate:g5": "node scripts/release-gate-test-groups.mjs --group 5",
7471
7818
  "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",
7819
+ "extension:build": "npm run extension:sync && node scripts/run-package-tool.mjs tsc -p extension/tsconfig.json && node scripts/copy-extension-assets.mjs",
7473
7820
  "extension:pack": "cd extension && zip -r ../opendevbrowser-extension.zip manifest.json popup.html canvas.html dist/ icons/",
7474
7821
  "extension:store": "node scripts/chrome-store-publish.mjs",
7475
7822
  "version:check": "node scripts/verify-versions.mjs",
@@ -7833,11 +8180,26 @@ async function main() {
7833
8180
  description: "Get daemon or session status",
7834
8181
  run: async () => runStatus(args)
7835
8182
  });
8183
+ registerCommand({
8184
+ name: "status-capabilities",
8185
+ description: "Inspect runtime capability discovery for the host and an optional session",
8186
+ run: async () => runStatusCapabilities(args)
8187
+ });
7836
8188
  registerCommand({
7837
8189
  name: "session-inspector",
7838
8190
  description: "Capture a session-first diagnostic summary with relay health and trace proof",
7839
8191
  run: async () => runSessionInspector(args)
7840
8192
  });
8193
+ registerCommand({
8194
+ name: "session-inspector-plan",
8195
+ description: "Inspect browser-scoped computer-use policy and safe suggested steps",
8196
+ run: async () => runSessionInspectorPlan(args)
8197
+ });
8198
+ registerCommand({
8199
+ name: "session-inspector-audit",
8200
+ description: "Capture a correlated audit bundle across desktop evidence, browser review, and policy state",
8201
+ run: async () => runSessionInspectorAudit(args)
8202
+ });
7841
8203
  registerCommand({
7842
8204
  name: "goto",
7843
8205
  description: "Navigate current session to a URL",
@@ -7858,6 +8220,11 @@ async function main() {
7858
8220
  description: "Capture a first-class review payload for the active page",
7859
8221
  run: async () => runReview(args)
7860
8222
  });
8223
+ registerCommand({
8224
+ name: "review-desktop",
8225
+ description: "Capture desktop-assisted browser review with read-only desktop evidence",
8226
+ run: async () => runReviewDesktop(args)
8227
+ });
7861
8228
  registerCommand({
7862
8229
  name: "annotate",
7863
8230
  description: "Request interactive annotations via direct or relay transport",
@@ -8123,6 +8490,11 @@ async function main() {
8123
8490
  description: "Run product presentation asset workflows",
8124
8491
  run: async () => runProductVideoCommand(args)
8125
8492
  });
8493
+ registerCommand({
8494
+ name: "inspiredesign",
8495
+ description: "Run inspiredesign workflows",
8496
+ run: async () => runInspiredesignCommand(args)
8497
+ });
8126
8498
  registerCommand({
8127
8499
  name: "artifacts",
8128
8500
  description: "Manage workflow artifact lifecycle",