@docyrus/docyrus 0.0.20 → 0.0.22

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 (76) hide show
  1. package/agent-loader.js +32 -1
  2. package/agent-loader.js.map +2 -2
  3. package/main.js +325 -71
  4. package/main.js.map +4 -4
  5. package/package.json +16 -3
  6. package/resources/chrome-tools/browser-content.js +103 -0
  7. package/resources/chrome-tools/browser-cookies.js +35 -0
  8. package/resources/chrome-tools/browser-eval.js +53 -0
  9. package/resources/chrome-tools/browser-hn-scraper.js +108 -0
  10. package/resources/chrome-tools/browser-nav.js +44 -0
  11. package/resources/chrome-tools/browser-pick.js +162 -0
  12. package/resources/chrome-tools/browser-screenshot.js +34 -0
  13. package/resources/chrome-tools/browser-start.js +86 -0
  14. package/resources/pi-agent/extensions/answer.ts +532 -0
  15. package/resources/pi-agent/extensions/context.ts +578 -0
  16. package/resources/pi-agent/extensions/control.ts +1779 -0
  17. package/resources/pi-agent/extensions/diff.ts +218 -0
  18. package/resources/pi-agent/extensions/files.ts +199 -0
  19. package/resources/pi-agent/extensions/loop.ts +446 -0
  20. package/resources/pi-agent/extensions/multi-edit.ts +835 -0
  21. package/resources/pi-agent/extensions/notify.ts +88 -0
  22. package/resources/pi-agent/extensions/pi-bash-live-view/LICENSE +21 -0
  23. package/resources/pi-agent/extensions/pi-bash-live-view/README.md +19 -0
  24. package/resources/pi-agent/extensions/pi-bash-live-view/index.ts +52 -0
  25. package/resources/pi-agent/extensions/pi-bash-live-view/package.json +61 -0
  26. package/resources/pi-agent/extensions/pi-bash-live-view/pty-execute.ts +97 -0
  27. package/resources/pi-agent/extensions/pi-bash-live-view/pty-kill.ts +25 -0
  28. package/resources/pi-agent/extensions/pi-bash-live-view/pty-session.ts +143 -0
  29. package/resources/pi-agent/extensions/pi-bash-live-view/spawn-helper.ts +31 -0
  30. package/resources/pi-agent/extensions/pi-bash-live-view/terminal-emulator.ts +439 -0
  31. package/resources/pi-agent/extensions/pi-bash-live-view/truncate.ts +68 -0
  32. package/resources/pi-agent/extensions/pi-bash-live-view/widget.ts +114 -0
  33. package/resources/pi-agent/extensions/pi-mcp-adapter/CHANGELOG.md +192 -0
  34. package/resources/pi-agent/extensions/pi-mcp-adapter/LICENSE +21 -0
  35. package/resources/pi-agent/extensions/pi-mcp-adapter/README.md +296 -0
  36. package/resources/pi-agent/extensions/pi-mcp-adapter/app-bridge.bundle.js +67 -0
  37. package/resources/pi-agent/extensions/pi-mcp-adapter/cli.js +108 -0
  38. package/resources/pi-agent/extensions/pi-mcp-adapter/commands.ts +211 -0
  39. package/resources/pi-agent/extensions/pi-mcp-adapter/config.ts +227 -0
  40. package/resources/pi-agent/extensions/pi-mcp-adapter/consent-manager.ts +64 -0
  41. package/resources/pi-agent/extensions/pi-mcp-adapter/direct-tools.ts +301 -0
  42. package/resources/pi-agent/extensions/pi-mcp-adapter/errors.ts +219 -0
  43. package/resources/pi-agent/extensions/pi-mcp-adapter/glimpse-ui.ts +80 -0
  44. package/resources/pi-agent/extensions/pi-mcp-adapter/host-html-template.ts +427 -0
  45. package/resources/pi-agent/extensions/pi-mcp-adapter/index.ts +232 -0
  46. package/resources/pi-agent/extensions/pi-mcp-adapter/init.ts +319 -0
  47. package/resources/pi-agent/extensions/pi-mcp-adapter/lifecycle.ts +93 -0
  48. package/resources/pi-agent/extensions/pi-mcp-adapter/logger.ts +169 -0
  49. package/resources/pi-agent/extensions/pi-mcp-adapter/mcp-panel.ts +713 -0
  50. package/resources/pi-agent/extensions/pi-mcp-adapter/metadata-cache.ts +191 -0
  51. package/resources/pi-agent/extensions/pi-mcp-adapter/npx-resolver.ts +419 -0
  52. package/resources/pi-agent/extensions/pi-mcp-adapter/oauth-handler.ts +56 -0
  53. package/resources/pi-agent/extensions/pi-mcp-adapter/package.json +85 -0
  54. package/resources/pi-agent/extensions/pi-mcp-adapter/paths.ts +29 -0
  55. package/resources/pi-agent/extensions/pi-mcp-adapter/proxy-modes.ts +635 -0
  56. package/resources/pi-agent/extensions/pi-mcp-adapter/resource-tools.ts +17 -0
  57. package/resources/pi-agent/extensions/pi-mcp-adapter/server-manager.ts +330 -0
  58. package/resources/pi-agent/extensions/pi-mcp-adapter/state.ts +41 -0
  59. package/resources/pi-agent/extensions/pi-mcp-adapter/tool-metadata.ts +144 -0
  60. package/resources/pi-agent/extensions/pi-mcp-adapter/tool-registrar.ts +46 -0
  61. package/resources/pi-agent/extensions/pi-mcp-adapter/types.ts +367 -0
  62. package/resources/pi-agent/extensions/pi-mcp-adapter/ui-resource-handler.ts +145 -0
  63. package/resources/pi-agent/extensions/pi-mcp-adapter/ui-server.ts +623 -0
  64. package/resources/pi-agent/extensions/pi-mcp-adapter/ui-session.ts +384 -0
  65. package/resources/pi-agent/extensions/pi-mcp-adapter/ui-stream-types.ts +89 -0
  66. package/resources/pi-agent/extensions/pi-mcp-adapter/utils.ts +75 -0
  67. package/resources/pi-agent/extensions/prompt-editor.ts +1315 -0
  68. package/resources/pi-agent/extensions/prompt-url-widget.ts +158 -0
  69. package/resources/pi-agent/extensions/redraws.ts +24 -0
  70. package/resources/pi-agent/extensions/review.ts +2160 -0
  71. package/resources/pi-agent/extensions/todos.ts +2076 -0
  72. package/resources/pi-agent/extensions/tps.ts +47 -0
  73. package/resources/pi-agent/extensions/whimsical.ts +474 -0
  74. package/resources/pi-agent/skills/changelog-generator/SKILL.md +425 -0
  75. package/resources/pi-agent/skills/docyrus-chrome-devtools-cli/SKILL.md +80 -0
  76. package/resources/pi-agent/skills/docyrus-platform/references/docyrus-cli-usage.md +51 -0
package/main.js CHANGED
@@ -18851,7 +18851,7 @@ var require_core3 = __commonJS({
18851
18851
  return match && match.index === 0;
18852
18852
  }
18853
18853
  var BACKREF_RE = /\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;
18854
- function join6(regexps, separator = "|") {
18854
+ function join7(regexps, separator = "|") {
18855
18855
  let numCaptures = 0;
18856
18856
  return regexps.map((regex) => {
18857
18857
  numCaptures += 1;
@@ -19155,7 +19155,7 @@ var require_core3 = __commonJS({
19155
19155
  this.exec = () => null;
19156
19156
  }
19157
19157
  const terminators = this.regexes.map((el) => el[1]);
19158
- this.matcherRe = langRe(join6(terminators), true);
19158
+ this.matcherRe = langRe(join7(terminators), true);
19159
19159
  this.lastIndex = 0;
19160
19160
  }
19161
19161
  /** @param {string} s */
@@ -124678,7 +124678,7 @@ function buildInputSchema(args, env2, options2) {
124678
124678
  // package.json
124679
124679
  var package_default = {
124680
124680
  name: "@docyrus/docyrus",
124681
- version: "0.0.20",
124681
+ version: "0.0.22",
124682
124682
  private: false,
124683
124683
  description: "Docyrus API CLI",
124684
124684
  main: "./main.js",
@@ -124686,17 +124686,30 @@ var package_default = {
124686
124686
  docyrus: "main.js"
124687
124687
  },
124688
124688
  dependencies: {
124689
+ "@mozilla/readability": "^0.6.0",
124689
124690
  "@clack/prompts": "^0.11.0",
124691
+ "@modelcontextprotocol/ext-apps": "^1.2.2",
124692
+ "@modelcontextprotocol/sdk": "^1.25.1",
124690
124693
  "@mariozechner/pi-ai": "0.61.0",
124691
- "@mariozechner/pi-coding-agent": "0.61.0",
124694
+ "@mariozechner/pi-coding-agent": "0.61.1",
124692
124695
  "@opentui/core": "^0.1.85",
124693
124696
  "@opentui/react": "^0.1.85",
124697
+ "@xterm/headless": "^5.5.0",
124698
+ cheerio: "^1.1.2",
124699
+ diff: "^8.0.2",
124694
124700
  incur: "^0.1.6",
124701
+ jsdom: "^27.0.1",
124695
124702
  marked: "^15.0.12",
124696
124703
  "marked-terminal": "^7.3.0",
124704
+ "node-pty": "^1.0.0",
124697
124705
  picocolors: "^1.1.1",
124706
+ "puppeteer-core": "^24.31.0",
124698
124707
  react: "^19.1.1",
124699
- undici: "^7.16.0"
124708
+ "strip-ansi": "^7.1.0",
124709
+ turndown: "^7.2.2",
124710
+ "turndown-plugin-gfm": "^1.0.2",
124711
+ undici: "^7.16.0",
124712
+ zod: "^4.3.6"
124700
124713
  },
124701
124714
  devDependencies: {
124702
124715
  "@types/react": "^19.1.13"
@@ -125688,9 +125701,244 @@ function createAuthCli(dependencies) {
125688
125701
  return authCli;
125689
125702
  }
125690
125703
 
125704
+ // src/commands/chromeCommands.ts
125705
+ var import_node_child_process2 = require("node:child_process");
125706
+ var import_node_fs3 = require("node:fs");
125707
+ var import_node_path4 = require("node:path");
125708
+ function summarizeFailure(result) {
125709
+ const stderr = result.stderr?.toString().trim();
125710
+ if (stderr && stderr.length > 0) {
125711
+ return stderr;
125712
+ }
125713
+ if (typeof result.status === "number") {
125714
+ return `Chrome tool exited with code ${result.status}.`;
125715
+ }
125716
+ if (result.signal) {
125717
+ return `Chrome tool exited due to signal ${result.signal}.`;
125718
+ }
125719
+ return "Chrome tool terminated unexpectedly.";
125720
+ }
125721
+ function resolveChromeToolsResourceRoot(options2 = {}) {
125722
+ const cwd = options2.cwd ?? process.cwd();
125723
+ const dirname6 = options2.dirname ?? __dirname;
125724
+ const fileExists = options2.existsSyncFn ?? import_node_fs3.existsSync;
125725
+ const candidates = options2.candidatePaths ?? [
125726
+ (0, import_node_path4.resolve)(cwd, "apps/api-cli/resources/chrome-tools"),
125727
+ (0, import_node_path4.resolve)(dirname6, "../resources/chrome-tools"),
125728
+ (0, import_node_path4.resolve)(dirname6, "resources/chrome-tools"),
125729
+ (0, import_node_path4.resolve)(cwd, "dist/apps/api-cli/resources/chrome-tools")
125730
+ ];
125731
+ const resolved = candidates.find((candidate) => fileExists(candidate));
125732
+ if (!resolved) {
125733
+ throw new UserInputError(`Unable to locate chrome tool resources. Checked: ${candidates.join(", ")}`);
125734
+ }
125735
+ return resolved;
125736
+ }
125737
+ function resolveChromeToolScriptPath(params) {
125738
+ const scriptPath = (0, import_node_path4.join)(params.resourceRoot, params.scriptName);
125739
+ if (!(0, import_node_fs3.existsSync)(scriptPath)) {
125740
+ throw new UserInputError(`Missing chrome tool script: ${scriptPath}`);
125741
+ }
125742
+ return scriptPath;
125743
+ }
125744
+ function parseTextOutput(rawOutput) {
125745
+ return rawOutput.trimEnd();
125746
+ }
125747
+ function parseJsonOutput(rawOutput) {
125748
+ const trimmedOutput = rawOutput.trim();
125749
+ if (!trimmedOutput) {
125750
+ return [];
125751
+ }
125752
+ try {
125753
+ return JSON.parse(trimmedOutput);
125754
+ } catch (error48) {
125755
+ throw new UserInputError("Chrome tool returned invalid JSON output.", {
125756
+ cause: error48,
125757
+ rawOutput: trimmedOutput
125758
+ });
125759
+ }
125760
+ }
125761
+ function executeChromeTool(params) {
125762
+ const resolveResourceRoot = params.resolveChromeToolsResourceRootFn ?? resolveChromeToolsResourceRoot;
125763
+ const resourceRoot = resolveResourceRoot({
125764
+ cwd: params.cwd
125765
+ });
125766
+ const scriptPath = resolveChromeToolScriptPath({
125767
+ resourceRoot,
125768
+ scriptName: params.scriptName
125769
+ });
125770
+ const spawnCommand = params.spawnSyncFn ?? import_node_child_process2.spawnSync;
125771
+ const processExecPath = params.processExecPath ?? process.execPath;
125772
+ const result = spawnCommand(processExecPath, [scriptPath, ...params.args], {
125773
+ encoding: "utf8",
125774
+ cwd: params.cwd ?? process.cwd(),
125775
+ env: {
125776
+ ...process.env
125777
+ }
125778
+ });
125779
+ if (result.error) {
125780
+ throw new UserInputError(`Unable to start chrome tool '${params.scriptName}': ${result.error.message}`, {
125781
+ cause: result.error
125782
+ });
125783
+ }
125784
+ if (result.status !== 0) {
125785
+ throw new UserInputError(`Chrome tool '${params.scriptName}' failed: ${summarizeFailure(result)}`);
125786
+ }
125787
+ const stdout = result.stdout?.toString() || "";
125788
+ if (params.outputMode === "json") {
125789
+ return parseJsonOutput(stdout);
125790
+ }
125791
+ return parseTextOutput(stdout);
125792
+ }
125793
+ function createChromeCli(options2 = {}) {
125794
+ const chromeCli = Cli_exports.create("chrome", {
125795
+ description: "Chrome DevTools browser automation commands",
125796
+ env: EnvSchema
125797
+ });
125798
+ chromeCli.command("start", {
125799
+ description: "Launch Chrome with remote debugging on :9222",
125800
+ options: external_exports.object({
125801
+ profile: external_exports.boolean().optional().describe("Copy your default Chrome profile (cookies, logins)")
125802
+ }),
125803
+ run: async (context) => {
125804
+ return executeChromeTool({
125805
+ scriptName: "browser-start.js",
125806
+ args: context.options.profile ? ["--profile"] : [],
125807
+ cwd: options2.cwd,
125808
+ processExecPath: options2.processExecPath,
125809
+ spawnSyncFn: options2.spawnSyncFn,
125810
+ resolveChromeToolsResourceRootFn: options2.resolveChromeToolsResourceRootFn
125811
+ });
125812
+ }
125813
+ });
125814
+ chromeCli.command("nav", {
125815
+ description: "Navigate the current Chrome tab or open a URL in a new tab",
125816
+ args: external_exports.object({
125817
+ url: external_exports.string().min(1)
125818
+ }),
125819
+ options: external_exports.object({
125820
+ new: external_exports.boolean().optional().describe("Open the URL in a new tab"),
125821
+ reload: external_exports.boolean().optional().describe("Force a reload after navigation")
125822
+ }),
125823
+ run: async (context) => {
125824
+ const args = [context.args.url];
125825
+ if (context.options.new) {
125826
+ args.push("--new");
125827
+ }
125828
+ if (context.options.reload) {
125829
+ args.push("--reload");
125830
+ }
125831
+ return executeChromeTool({
125832
+ scriptName: "browser-nav.js",
125833
+ args,
125834
+ cwd: options2.cwd,
125835
+ processExecPath: options2.processExecPath,
125836
+ spawnSyncFn: options2.spawnSyncFn,
125837
+ resolveChromeToolsResourceRootFn: options2.resolveChromeToolsResourceRootFn
125838
+ });
125839
+ }
125840
+ });
125841
+ chromeCli.command("eval", {
125842
+ description: "Evaluate JavaScript in the active Chrome tab",
125843
+ args: external_exports.object({
125844
+ code: external_exports.string().min(1)
125845
+ }),
125846
+ run: async (context) => {
125847
+ return executeChromeTool({
125848
+ scriptName: "browser-eval.js",
125849
+ args: [context.args.code],
125850
+ cwd: options2.cwd,
125851
+ processExecPath: options2.processExecPath,
125852
+ spawnSyncFn: options2.spawnSyncFn,
125853
+ resolveChromeToolsResourceRootFn: options2.resolveChromeToolsResourceRootFn
125854
+ });
125855
+ }
125856
+ });
125857
+ chromeCli.command("screenshot", {
125858
+ description: "Capture a screenshot of the active Chrome tab",
125859
+ run: async () => {
125860
+ return executeChromeTool({
125861
+ scriptName: "browser-screenshot.js",
125862
+ args: [],
125863
+ cwd: options2.cwd,
125864
+ processExecPath: options2.processExecPath,
125865
+ spawnSyncFn: options2.spawnSyncFn,
125866
+ resolveChromeToolsResourceRootFn: options2.resolveChromeToolsResourceRootFn
125867
+ });
125868
+ }
125869
+ });
125870
+ chromeCli.command("pick", {
125871
+ description: "Interactively pick DOM elements in the active Chrome tab",
125872
+ args: external_exports.object({
125873
+ message: external_exports.string().min(1)
125874
+ }),
125875
+ run: async (context) => {
125876
+ return executeChromeTool({
125877
+ scriptName: "browser-pick.js",
125878
+ args: [context.args.message],
125879
+ cwd: options2.cwd,
125880
+ processExecPath: options2.processExecPath,
125881
+ spawnSyncFn: options2.spawnSyncFn,
125882
+ resolveChromeToolsResourceRootFn: options2.resolveChromeToolsResourceRootFn
125883
+ });
125884
+ }
125885
+ });
125886
+ chromeCli.command("cookies", {
125887
+ description: "Show cookies for the active Chrome tab",
125888
+ run: async () => {
125889
+ return executeChromeTool({
125890
+ scriptName: "browser-cookies.js",
125891
+ args: [],
125892
+ cwd: options2.cwd,
125893
+ processExecPath: options2.processExecPath,
125894
+ spawnSyncFn: options2.spawnSyncFn,
125895
+ resolveChromeToolsResourceRootFn: options2.resolveChromeToolsResourceRootFn
125896
+ });
125897
+ }
125898
+ });
125899
+ chromeCli.command("content", {
125900
+ description: "Extract readable markdown content from a URL in Chrome",
125901
+ args: external_exports.object({
125902
+ url: external_exports.string().min(1)
125903
+ }),
125904
+ run: async (context) => {
125905
+ return executeChromeTool({
125906
+ scriptName: "browser-content.js",
125907
+ args: [context.args.url],
125908
+ cwd: options2.cwd,
125909
+ processExecPath: options2.processExecPath,
125910
+ spawnSyncFn: options2.spawnSyncFn,
125911
+ resolveChromeToolsResourceRootFn: options2.resolveChromeToolsResourceRootFn
125912
+ });
125913
+ }
125914
+ });
125915
+ chromeCli.command("hn-scraper", {
125916
+ description: "Scrape Hacker News submissions as JSON",
125917
+ options: external_exports.object({
125918
+ limit: external_exports.number().int().positive().optional().describe("Maximum number of submissions to return")
125919
+ }),
125920
+ run: async (context) => {
125921
+ const args = [];
125922
+ if (context.options.limit !== void 0) {
125923
+ args.push("--limit", String(context.options.limit));
125924
+ }
125925
+ return executeChromeTool({
125926
+ scriptName: "browser-hn-scraper.js",
125927
+ args,
125928
+ outputMode: "json",
125929
+ cwd: options2.cwd,
125930
+ processExecPath: options2.processExecPath,
125931
+ spawnSyncFn: options2.spawnSyncFn,
125932
+ resolveChromeToolsResourceRootFn: options2.resolveChromeToolsResourceRootFn
125933
+ });
125934
+ }
125935
+ });
125936
+ return chromeCli;
125937
+ }
125938
+
125691
125939
  // src/services/inputReader.ts
125692
125940
  var import_promises2 = require("node:fs/promises");
125693
- var import_node_path4 = require("node:path");
125941
+ var import_node_path5 = require("node:path");
125694
125942
  async function readStdinText() {
125695
125943
  if (process.stdin.isTTY) {
125696
125944
  return "";
@@ -125793,7 +126041,7 @@ async function readDataInput(params) {
125793
126041
  cause: error48
125794
126042
  });
125795
126043
  }
125796
- const extension = (0, import_node_path4.extname)(trimmedFromFile).toLowerCase();
126044
+ const extension = (0, import_node_path5.extname)(trimmedFromFile).toLowerCase();
125797
126045
  if (extension === ".csv") {
125798
126046
  return parseCsvData(content, "--from-file");
125799
126047
  }
@@ -126591,7 +126839,7 @@ function createEnvCli(dependencies) {
126591
126839
 
126592
126840
  // src/services/studioPayload.ts
126593
126841
  var import_promises4 = require("node:fs/promises");
126594
- var import_node_path5 = require("node:path");
126842
+ var import_node_path6 = require("node:path");
126595
126843
  async function readStdinText2() {
126596
126844
  if (process.stdin.isTTY) {
126597
126845
  return "";
@@ -126622,7 +126870,7 @@ async function readStudioWriteInput(params) {
126622
126870
  throw new UserInputError("Provide either --data or --from-file, not both.");
126623
126871
  }
126624
126872
  if (trimmedFromFile) {
126625
- const extension = (0, import_node_path5.extname)(trimmedFromFile).toLowerCase();
126873
+ const extension = (0, import_node_path6.extname)(trimmedFromFile).toLowerCase();
126626
126874
  if (extension && extension !== ".json") {
126627
126875
  throw new UserInputError("Studio commands support only JSON files in --from-file.");
126628
126876
  }
@@ -127625,10 +127873,10 @@ function createStudioCli(dependencies) {
127625
127873
  }
127626
127874
 
127627
127875
  // src/commands/tuiCommand.ts
127628
- var import_node_child_process2 = require("node:child_process");
127629
- var import_node_fs3 = require("node:fs");
127630
- var import_node_path6 = require("node:path");
127631
- function summarizeFailure(result) {
127876
+ var import_node_child_process3 = require("node:child_process");
127877
+ var import_node_fs4 = require("node:fs");
127878
+ var import_node_path7 = require("node:path");
127879
+ function summarizeFailure2(result) {
127632
127880
  const stderr = result.stderr?.toString().trim();
127633
127881
  if (stderr && stderr.length > 0) {
127634
127882
  return stderr;
@@ -127644,23 +127892,23 @@ function summarizeFailure(result) {
127644
127892
  function resolveCliScriptPath() {
127645
127893
  const argvScript = process.argv[1];
127646
127894
  if (argvScript && argvScript.trim().length > 0) {
127647
- return (0, import_node_path6.isAbsolute)(argvScript) ? argvScript : (0, import_node_path6.resolve)(process.cwd(), argvScript);
127895
+ return (0, import_node_path7.isAbsolute)(argvScript) ? argvScript : (0, import_node_path7.resolve)(process.cwd(), argvScript);
127648
127896
  }
127649
127897
  return __filename;
127650
127898
  }
127651
127899
  function resolveOpenTuiEntryPath(options2 = {}) {
127652
127900
  const cwd = options2.cwd ?? process.cwd();
127653
127901
  const dirname6 = options2.dirname ?? __dirname;
127654
- const fileExists = options2.existsSyncFn ?? import_node_fs3.existsSync;
127902
+ const fileExists = options2.existsSyncFn ?? import_node_fs4.existsSync;
127655
127903
  const candidates = [
127656
127904
  // Source/dev mode in monorepo. Prefer this first so Bun resolves deps via
127657
127905
  // apps/api-cli/node_modules in workspace runs (e.g. `pnpm docyrus tui`).
127658
- (0, import_node_path6.resolve)(cwd, "apps/api-cli/src/tui/opentuiMain.tsx"),
127659
- (0, import_node_path6.resolve)(dirname6, "../tui/opentuiMain.tsx"),
127906
+ (0, import_node_path7.resolve)(cwd, "apps/api-cli/src/tui/opentuiMain.tsx"),
127907
+ (0, import_node_path7.resolve)(dirname6, "../tui/opentuiMain.tsx"),
127660
127908
  // Dist mode (bundled command runtime)
127661
- (0, import_node_path6.resolve)(dirname6, "tui.mjs"),
127662
- (0, import_node_path6.resolve)(dirname6, "../tui.mjs"),
127663
- (0, import_node_path6.resolve)(cwd, "dist/apps/api-cli/tui.mjs")
127909
+ (0, import_node_path7.resolve)(dirname6, "tui.mjs"),
127910
+ (0, import_node_path7.resolve)(dirname6, "../tui.mjs"),
127911
+ (0, import_node_path7.resolve)(cwd, "dist/apps/api-cli/tui.mjs")
127664
127912
  ];
127665
127913
  const resolved = candidates.find((candidate) => fileExists(candidate));
127666
127914
  if (!resolved) {
@@ -127671,7 +127919,7 @@ function resolveOpenTuiEntryPath(options2 = {}) {
127671
127919
  return resolved;
127672
127920
  }
127673
127921
  function ensureBunAvailable(options2 = {}) {
127674
- const spawnCommand = options2.spawnSyncFn ?? import_node_child_process2.spawnSync;
127922
+ const spawnCommand = options2.spawnSyncFn ?? import_node_child_process3.spawnSync;
127675
127923
  const result = spawnCommand("bun", ["--version"], {
127676
127924
  encoding: "utf8"
127677
127925
  });
@@ -127685,7 +127933,7 @@ function ensureBunAvailable(options2 = {}) {
127685
127933
  }
127686
127934
  }
127687
127935
  function launchOpenTuiProcess(options2) {
127688
- const spawnCommand = options2.spawnSyncFn ?? import_node_child_process2.spawnSync;
127936
+ const spawnCommand = options2.spawnSyncFn ?? import_node_child_process3.spawnSync;
127689
127937
  const result = spawnCommand("bun", [options2.entryPath], {
127690
127938
  stdio: ["inherit", "inherit", "pipe"],
127691
127939
  encoding: "utf8",
@@ -127701,7 +127949,7 @@ function launchOpenTuiProcess(options2) {
127701
127949
  }
127702
127950
  if (result.status !== 0) {
127703
127951
  throw new UserInputError(
127704
- `OpenTUI process failed: ${summarizeFailure(result)}`
127952
+ `OpenTUI process failed: ${summarizeFailure2(result)}`
127705
127953
  );
127706
127954
  }
127707
127955
  }
@@ -128446,7 +128694,7 @@ var AuthSessionService = class {
128446
128694
 
128447
128695
  // src/services/authStore.ts
128448
128696
  var import_promises5 = require("node:fs/promises");
128449
- var import_node_path7 = require("node:path");
128697
+ var import_node_path8 = require("node:path");
128450
128698
  function createEmptyState() {
128451
128699
  return {
128452
128700
  version: 2,
@@ -128521,7 +128769,7 @@ var AuthStore = class {
128521
128769
  });
128522
128770
  }
128523
128771
  const normalized = normalizeState(validated.data);
128524
- const directory = (0, import_node_path7.dirname)(this.authFilePath);
128772
+ const directory = (0, import_node_path8.dirname)(this.authFilePath);
128525
128773
  await (0, import_promises5.mkdir)(directory, {
128526
128774
  recursive: true,
128527
128775
  mode: 448
@@ -128736,7 +128984,7 @@ var AuthStore = class {
128736
128984
 
128737
128985
  // src/services/environmentConfig.ts
128738
128986
  var import_promises6 = require("node:fs/promises");
128739
- var import_node_path8 = require("node:path");
128987
+ var import_node_path9 = require("node:path");
128740
128988
  var ENVIRONMENT_ID_ALIASES = {
128741
128989
  "local-development": "dev",
128742
128990
  prod: "live"
@@ -128856,7 +129104,7 @@ var EnvironmentConfigService = class {
128856
129104
  });
128857
129105
  }
128858
129106
  const normalized = normalizeState2(validated.data);
128859
- const directory = (0, import_node_path8.dirname)(this.configFilePath);
129107
+ const directory = (0, import_node_path9.dirname)(this.configFilePath);
128860
129108
  await (0, import_promises6.mkdir)(directory, {
128861
129109
  recursive: true,
128862
129110
  mode: 448
@@ -128932,10 +129180,10 @@ var EnvironmentConfigService = class {
128932
129180
  };
128933
129181
 
128934
129182
  // src/services/piAgentLauncher.ts
128935
- var import_node_child_process3 = require("node:child_process");
128936
- var import_node_fs4 = require("node:fs");
129183
+ var import_node_child_process4 = require("node:child_process");
129184
+ var import_node_fs5 = require("node:fs");
128937
129185
  var import_promises7 = require("node:fs/promises");
128938
- var import_node_path9 = require("node:path");
129186
+ var import_node_path10 = require("node:path");
128939
129187
  var DOCYRUS_EXTERNAL_SKILL_SOURCE = "docyrus/agent-skills";
128940
129188
  var DOCYRUS_PACKAGED_PLATFORM_SKILL_NAME = "docyrus-platform";
128941
129189
  var DOCYRUS_MIGRATED_SKILL_NAMES = [
@@ -128953,7 +129201,7 @@ var DOCYRUS_EXTERNAL_SKILL_AGENT_IDS = [
128953
129201
  "windsurf"
128954
129202
  ];
128955
129203
  var DOCYRUS_EXTERNAL_SKILL_MARKER_FILE = ".docyrus-external-skills-installed.json";
128956
- function summarizeFailure2(result) {
129204
+ function summarizeFailure3(result) {
128957
129205
  const stderr = result.stderr?.toString().trim();
128958
129206
  if (stderr && stderr.length > 0) {
128959
129207
  return stderr;
@@ -128969,12 +129217,12 @@ function summarizeFailure2(result) {
128969
129217
  function resolvePackagedPiResourceRoot(options2 = {}) {
128970
129218
  const cwd = options2.cwd ?? process.cwd();
128971
129219
  const dirname6 = options2.dirname ?? __dirname;
128972
- const fileExists = options2.existsSyncFn ?? import_node_fs4.existsSync;
129220
+ const fileExists = options2.existsSyncFn ?? import_node_fs5.existsSync;
128973
129221
  const candidates = [
128974
- (0, import_node_path9.resolve)(cwd, "apps/api-cli/resources/pi-agent"),
128975
- (0, import_node_path9.resolve)(dirname6, "../resources/pi-agent"),
128976
- (0, import_node_path9.resolve)(dirname6, "resources/pi-agent"),
128977
- (0, import_node_path9.resolve)(cwd, "dist/apps/api-cli/resources/pi-agent")
129222
+ (0, import_node_path10.resolve)(cwd, "apps/api-cli/resources/pi-agent"),
129223
+ (0, import_node_path10.resolve)(dirname6, "../resources/pi-agent"),
129224
+ (0, import_node_path10.resolve)(dirname6, "resources/pi-agent"),
129225
+ (0, import_node_path10.resolve)(cwd, "dist/apps/api-cli/resources/pi-agent")
128978
129226
  ];
128979
129227
  const resolved = candidates.find((candidate) => fileExists(candidate));
128980
129228
  if (!resolved) {
@@ -128985,7 +129233,7 @@ function resolvePackagedPiResourceRoot(options2 = {}) {
128985
129233
  function resolveDocyrusPiLoaderEntryPath(options2 = {}) {
128986
129234
  const cwd = options2.cwd ?? process.cwd();
128987
129235
  const dirname6 = options2.dirname ?? __dirname;
128988
- const fileExists = options2.existsSyncFn ?? import_node_fs4.existsSync;
129236
+ const fileExists = options2.existsSyncFn ?? import_node_fs5.existsSync;
128989
129237
  const seen = /* @__PURE__ */ new Set();
128990
129238
  const candidates = options2.candidatePaths ?? [];
128991
129239
  const addCandidate = (candidate) => {
@@ -128995,23 +129243,23 @@ function resolveDocyrusPiLoaderEntryPath(options2 = {}) {
128995
129243
  }
128996
129244
  };
128997
129245
  const collectAncestorCandidates = (startDir) => {
128998
- let currentDir = (0, import_node_path9.resolve)(startDir);
129246
+ let currentDir = (0, import_node_path10.resolve)(startDir);
128999
129247
  while (true) {
129000
- addCandidate((0, import_node_path9.join)(currentDir, "dist", "apps", "api-cli", "agent-loader.js"));
129001
- addCandidate((0, import_node_path9.join)(currentDir, "agent-loader.js"));
129002
- if ((0, import_node_path9.basename)(currentDir) === "dist") {
129003
- addCandidate((0, import_node_path9.join)(currentDir, "apps", "api-cli", "agent-loader.js"));
129248
+ addCandidate((0, import_node_path10.join)(currentDir, "dist", "apps", "api-cli", "agent-loader.js"));
129249
+ addCandidate((0, import_node_path10.join)(currentDir, "agent-loader.js"));
129250
+ if ((0, import_node_path10.basename)(currentDir) === "dist") {
129251
+ addCandidate((0, import_node_path10.join)(currentDir, "apps", "api-cli", "agent-loader.js"));
129004
129252
  }
129005
- const parentDir = (0, import_node_path9.resolve)(currentDir, "..");
129253
+ const parentDir = (0, import_node_path10.resolve)(currentDir, "..");
129006
129254
  if (parentDir === currentDir) {
129007
129255
  break;
129008
129256
  }
129009
129257
  currentDir = parentDir;
129010
129258
  }
129011
129259
  };
129012
- addCandidate((0, import_node_path9.resolve)(cwd, "dist/apps/api-cli/agent-loader.js"));
129013
- addCandidate((0, import_node_path9.resolve)(dirname6, "../agent-loader.js"));
129014
- addCandidate((0, import_node_path9.resolve)(dirname6, "agent-loader.js"));
129260
+ addCandidate((0, import_node_path10.resolve)(cwd, "dist/apps/api-cli/agent-loader.js"));
129261
+ addCandidate((0, import_node_path10.resolve)(dirname6, "../agent-loader.js"));
129262
+ addCandidate((0, import_node_path10.resolve)(dirname6, "agent-loader.js"));
129015
129263
  collectAncestorCandidates(cwd);
129016
129264
  collectAncestorCandidates(dirname6);
129017
129265
  const resolved = candidates.find((candidate) => fileExists(candidate));
@@ -129023,7 +129271,7 @@ function resolveDocyrusPiLoaderEntryPath(options2 = {}) {
129023
129271
  function resolveInstalledPiPackageRootPath(options2 = {}) {
129024
129272
  const cwd = options2.cwd ?? process.cwd();
129025
129273
  const dirname6 = options2.dirname ?? __dirname;
129026
- const fileExists = options2.existsSyncFn ?? import_node_fs4.existsSync;
129274
+ const fileExists = options2.existsSyncFn ?? import_node_fs5.existsSync;
129027
129275
  const seen = /* @__PURE__ */ new Set();
129028
129276
  const candidates = options2.candidatePaths ?? [];
129029
129277
  const addCandidate = (candidate) => {
@@ -129033,27 +129281,27 @@ function resolveInstalledPiPackageRootPath(options2 = {}) {
129033
129281
  }
129034
129282
  };
129035
129283
  const collectAncestorCandidates = (startDir) => {
129036
- let currentDir = (0, import_node_path9.resolve)(startDir);
129284
+ let currentDir = (0, import_node_path10.resolve)(startDir);
129037
129285
  while (true) {
129038
- addCandidate((0, import_node_path9.join)(currentDir, "node_modules", "@mariozechner", "pi-coding-agent", "package.json"));
129039
- if ((0, import_node_path9.basename)(currentDir) === "node_modules") {
129040
- addCandidate((0, import_node_path9.join)(currentDir, "@mariozechner", "pi-coding-agent", "package.json"));
129286
+ addCandidate((0, import_node_path10.join)(currentDir, "node_modules", "@mariozechner", "pi-coding-agent", "package.json"));
129287
+ if ((0, import_node_path10.basename)(currentDir) === "node_modules") {
129288
+ addCandidate((0, import_node_path10.join)(currentDir, "@mariozechner", "pi-coding-agent", "package.json"));
129041
129289
  }
129042
- const parentDir = (0, import_node_path9.resolve)(currentDir, "..");
129290
+ const parentDir = (0, import_node_path10.resolve)(currentDir, "..");
129043
129291
  if (parentDir === currentDir) {
129044
129292
  break;
129045
129293
  }
129046
129294
  currentDir = parentDir;
129047
129295
  }
129048
129296
  };
129049
- addCandidate((0, import_node_path9.resolve)(cwd, "apps/api-cli/node_modules/@mariozechner/pi-coding-agent/package.json"));
129297
+ addCandidate((0, import_node_path10.resolve)(cwd, "apps/api-cli/node_modules/@mariozechner/pi-coding-agent/package.json"));
129050
129298
  collectAncestorCandidates(cwd);
129051
129299
  collectAncestorCandidates(dirname6);
129052
129300
  const resolvedPackageJson = candidates.find((candidate) => fileExists(candidate));
129053
129301
  if (!resolvedPackageJson) {
129054
129302
  throw new UserInputError(`Unable to locate the installed pi package root. Checked: ${candidates.join(", ")}`);
129055
129303
  }
129056
- return (0, import_node_path9.resolve)(resolvedPackageJson, "..");
129304
+ return (0, import_node_path10.resolve)(resolvedPackageJson, "..");
129057
129305
  }
129058
129306
  function createPiAgentRuntimeSkill(params) {
129059
129307
  const commandPrefix = params.scope === "global" ? "docyrus -g" : "docyrus";
@@ -129100,8 +129348,8 @@ function createPiAgentRuntimeSkill(params) {
129100
129348
  ].join("\n");
129101
129349
  }
129102
129350
  async function syncPackagedSkills(params) {
129103
- const sourceSkillsRoot = (0, import_node_path9.join)(params.resourceRoot, "skills");
129104
- const targetSkillsRoot = (0, import_node_path9.join)(params.agentRootPath, "skills");
129351
+ const sourceSkillsRoot = (0, import_node_path10.join)(params.resourceRoot, "skills");
129352
+ const targetSkillsRoot = (0, import_node_path10.join)(params.agentRootPath, "skills");
129105
129353
  await (0, import_promises7.mkdir)(targetSkillsRoot, {
129106
129354
  recursive: true,
129107
129355
  mode: 448
@@ -129110,25 +129358,25 @@ async function syncPackagedSkills(params) {
129110
129358
  withFileTypes: true
129111
129359
  });
129112
129360
  await Promise.all(DOCYRUS_MIGRATED_SKILL_NAMES.map(async (skillName) => {
129113
- await (0, import_promises7.rm)((0, import_node_path9.join)(targetSkillsRoot, skillName), {
129361
+ await (0, import_promises7.rm)((0, import_node_path10.join)(targetSkillsRoot, skillName), {
129114
129362
  recursive: true,
129115
129363
  force: true
129116
129364
  });
129117
129365
  }));
129118
129366
  await Promise.all(entries.map(async (entry) => {
129119
- await (0, import_promises7.cp)((0, import_node_path9.join)(sourceSkillsRoot, entry.name), (0, import_node_path9.join)(targetSkillsRoot, entry.name), {
129367
+ await (0, import_promises7.cp)((0, import_node_path10.join)(sourceSkillsRoot, entry.name), (0, import_node_path10.join)(targetSkillsRoot, entry.name), {
129120
129368
  recursive: true,
129121
129369
  force: true
129122
129370
  });
129123
129371
  }));
129124
129372
  }
129125
129373
  async function writeRuntimeSkill(params) {
129126
- const runtimeSkillDir = (0, import_node_path9.join)(params.agentRootPath, "skills", "docyrus-runtime-context");
129374
+ const runtimeSkillDir = (0, import_node_path10.join)(params.agentRootPath, "skills", "docyrus-runtime-context");
129127
129375
  await (0, import_promises7.mkdir)(runtimeSkillDir, {
129128
129376
  recursive: true,
129129
129377
  mode: 448
129130
129378
  });
129131
- await (0, import_promises7.writeFile)((0, import_node_path9.join)(runtimeSkillDir, "SKILL.md"), `${params.content}
129379
+ await (0, import_promises7.writeFile)((0, import_node_path10.join)(runtimeSkillDir, "SKILL.md"), `${params.content}
129132
129380
  `, {
129133
129381
  encoding: "utf8",
129134
129382
  mode: 384
@@ -129173,8 +129421,8 @@ function createPackagedDocyrusPlatformInstallArgs(params) {
129173
129421
  return args;
129174
129422
  }
129175
129423
  async function installExternalDocyrusSkillsOnce(params) {
129176
- const markerPath = (0, import_node_path9.join)(params.agentRootPath, DOCYRUS_EXTERNAL_SKILL_MARKER_FILE);
129177
- if ((0, import_node_fs4.existsSync)(markerPath)) {
129424
+ const markerPath = (0, import_node_path10.join)(params.agentRootPath, DOCYRUS_EXTERNAL_SKILL_MARKER_FILE);
129425
+ if ((0, import_node_fs5.existsSync)(markerPath)) {
129178
129426
  return;
129179
129427
  }
129180
129428
  const result = params.spawnCommand(resolveNpxCommand(), createDocyrusSkillsInstallArgs(params.scope), {
@@ -129187,7 +129435,7 @@ async function installExternalDocyrusSkillsOnce(params) {
129187
129435
  });
129188
129436
  if (result.error || result.status !== 0) {
129189
129437
  process.stderr.write(
129190
- `[docyrus] Automatic Docyrus skill install failed. Continuing without it: ${result.error?.message || summarizeFailure2(result)}
129438
+ `[docyrus] Automatic Docyrus skill install failed. Continuing without it: ${result.error?.message || summarizeFailure3(result)}
129191
129439
  `
129192
129440
  );
129193
129441
  return;
@@ -129205,11 +129453,11 @@ async function installExternalDocyrusSkillsOnce(params) {
129205
129453
  });
129206
129454
  }
129207
129455
  function resolvePackagedDocyrusPlatformSkillPath(resourceRoot) {
129208
- return (0, import_node_path9.join)(resourceRoot, "skills", DOCYRUS_PACKAGED_PLATFORM_SKILL_NAME);
129456
+ return (0, import_node_path10.join)(resourceRoot, "skills", DOCYRUS_PACKAGED_PLATFORM_SKILL_NAME);
129209
129457
  }
129210
129458
  function installPackagedDocyrusPlatformSkill(params) {
129211
129459
  const skillSourcePath = resolvePackagedDocyrusPlatformSkillPath(params.resourceRoot);
129212
- if (!(0, import_node_fs4.existsSync)(skillSourcePath)) {
129460
+ if (!(0, import_node_fs5.existsSync)(skillSourcePath)) {
129213
129461
  process.stderr.write("[docyrus] Packaged docyrus-platform skill is missing. Continuing without agent sync.\n");
129214
129462
  return;
129215
129463
  }
@@ -129230,7 +129478,7 @@ function installPackagedDocyrusPlatformSkill(params) {
129230
129478
  );
129231
129479
  if (result.error || result.status !== 0) {
129232
129480
  process.stderr.write(
129233
- `[docyrus] Automatic docyrus-platform skill sync failed. Continuing without it: ${result.error?.message || summarizeFailure2(result)}
129481
+ `[docyrus] Automatic docyrus-platform skill sync failed. Continuing without it: ${result.error?.message || summarizeFailure3(result)}
129234
129482
  `
129235
129483
  );
129236
129484
  }
@@ -129246,7 +129494,7 @@ function validatePiAgentLaunchRequest(params) {
129246
129494
  function createPiAgentLauncher(options2) {
129247
129495
  const cwd = options2.cwd ?? process.cwd();
129248
129496
  const stdinIsTTY = options2.stdinIsTTY ?? process.stdin.isTTY ?? false;
129249
- const spawnCommand = options2.spawnSyncFn ?? import_node_child_process3.spawnSync;
129497
+ const spawnCommand = options2.spawnSyncFn ?? import_node_child_process4.spawnSync;
129250
129498
  const processExecPath = options2.processExecPath ?? process.execPath;
129251
129499
  const resolveResourceRoot = options2.resolvePackagedPiResourceRootFn ?? resolvePackagedPiResourceRoot;
129252
129500
  const resolveLoaderPath = options2.resolveDocyrusPiLoaderEntryPathFn ?? resolveDocyrusPiLoaderEntryPath;
@@ -129307,14 +129555,14 @@ function createPiAgentLauncher(options2) {
129307
129555
  });
129308
129556
  }
129309
129557
  if (result.status !== 0) {
129310
- throw new UserInputError(`Docyrus pi loader failed: ${summarizeFailure2(result)}`);
129558
+ throw new UserInputError(`Docyrus pi loader failed: ${summarizeFailure3(result)}`);
129311
129559
  }
129312
129560
  };
129313
129561
  }
129314
129562
 
129315
129563
  // src/services/tenantOpenApi.ts
129316
129564
  var import_promises8 = require("node:fs/promises");
129317
- var import_node_path10 = require("node:path");
129565
+ var import_node_path11 = require("node:path");
129318
129566
  function resolveSourceUrl(tenantId, template) {
129319
129567
  return template.replace("{tenantId}", encodeURIComponent(tenantId));
129320
129568
  }
@@ -129338,7 +129586,7 @@ var TenantOpenApiService = class {
129338
129586
  }
129339
129587
  async #writeOpenApiFile(tenantId, parsedContent) {
129340
129588
  const filePath = this.getTenantOpenApiFilePath(tenantId);
129341
- await (0, import_promises8.mkdir)((0, import_node_path10.dirname)(filePath), {
129589
+ await (0, import_promises8.mkdir)((0, import_node_path11.dirname)(filePath), {
129342
129590
  recursive: true,
129343
129591
  mode: 448
129344
129592
  });
@@ -129384,7 +129632,7 @@ var TenantOpenApiService = class {
129384
129632
  throw new AuthSessionError("Tenant ID is required to resolve OpenAPI spec path.");
129385
129633
  }
129386
129634
  const rootPath = this.params?.rootPath || TENANT_OPENAPI_ROOT_PATH;
129387
- return (0, import_node_path10.join)(rootPath, normalizedTenantId, "openapi.json");
129635
+ return (0, import_node_path11.join)(rootPath, normalizedTenantId, "openapi.json");
129388
129636
  }
129389
129637
  async downloadTenantOpenApi(tenantId, options2 = {}) {
129390
129638
  const normalizedTenantId = tenantId.trim();
@@ -129447,6 +129695,9 @@ var ROOT_HELP_COMMANDS = [
129447
129695
  { command: 'ai "<prompt>"', description: "Send a prompt to the default Docyrus CLI agent" },
129448
129696
  { command: "agent [prompt]", description: "Launch the scoped Docyrus pi assistant" },
129449
129697
  { command: "coder [prompt]", description: "Launch the scoped Docyrus pi coding agent" },
129698
+ { command: "chrome start", description: "Launch Chrome with remote debugging on :9222" },
129699
+ { command: "chrome nav <url>", description: "Navigate the active Chrome tab" },
129700
+ { command: "chrome content <url>", description: "Extract readable page content as markdown" },
129450
129701
  { command: "discover api", description: "Download active tenant OpenAPI spec" },
129451
129702
  { command: "discover namespaces", description: "List namespaces from tenant OpenAPI spec" },
129452
129703
  { command: "discover path <prefix>", description: "List endpoint paths by prefix" },
@@ -129537,6 +129788,9 @@ function createDocyrusCli(params) {
129537
129788
  cli2.command(createCoderCli({
129538
129789
  launchPiAgent: piAgentLauncher
129539
129790
  }));
129791
+ cli2.command(createChromeCli({
129792
+ cwd: params?.cwd
129793
+ }));
129540
129794
  cli2.command(createDsCli({
129541
129795
  createApiClient,
129542
129796
  environmentConfigService,