dev3000 0.0.174 → 0.0.175

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 (71) hide show
  1. package/README.md +0 -4
  2. package/dist/cdp-monitor.d.ts +3 -0
  3. package/dist/cdp-monitor.d.ts.map +1 -1
  4. package/dist/cdp-monitor.js +225 -38
  5. package/dist/cdp-monitor.js.map +1 -1
  6. package/dist/cli.js +172 -217
  7. package/dist/cli.js.map +1 -1
  8. package/dist/commands/crawl.d.ts.map +1 -1
  9. package/dist/commands/crawl.js +4 -43
  10. package/dist/commands/crawl.js.map +1 -1
  11. package/dist/commands/errors.d.ts.map +1 -1
  12. package/dist/commands/errors.js +4 -53
  13. package/dist/commands/errors.js.map +1 -1
  14. package/dist/commands/fix.d.ts.map +1 -1
  15. package/dist/commands/fix.js +5 -74
  16. package/dist/commands/fix.js.map +1 -1
  17. package/dist/commands/logs.d.ts.map +1 -1
  18. package/dist/commands/logs.js +4 -53
  19. package/dist/commands/logs.js.map +1 -1
  20. package/dist/commands/skill-runner.d.ts +14 -0
  21. package/dist/commands/skill-runner.d.ts.map +1 -0
  22. package/dist/commands/skill-runner.js +494 -0
  23. package/dist/commands/skill-runner.js.map +1 -0
  24. package/dist/dev-environment.d.ts +4 -3
  25. package/dist/dev-environment.d.ts.map +1 -1
  26. package/dist/dev-environment.js +111 -95
  27. package/dist/dev-environment.js.map +1 -1
  28. package/dist/skills/d3k/internal-skill.md +145 -0
  29. package/dist/skills/index.test.ts +28 -1
  30. package/dist/skills/index.ts +58 -7
  31. package/dist/utils/agent-browser.d.ts.map +1 -1
  32. package/dist/utils/agent-browser.js +6 -3
  33. package/dist/utils/agent-browser.js.map +1 -1
  34. package/dist/utils/agent-detection.d.ts +1 -0
  35. package/dist/utils/agent-detection.d.ts.map +1 -1
  36. package/dist/utils/agent-detection.js +11 -0
  37. package/dist/utils/agent-detection.js.map +1 -1
  38. package/dist/utils/agent-selection.js +3 -3
  39. package/dist/utils/agent-selection.js.map +1 -1
  40. package/dist/utils/browser-command-argv.d.ts +1 -1
  41. package/dist/utils/browser-command-argv.d.ts.map +1 -1
  42. package/dist/utils/browser-command-argv.js +1 -1
  43. package/dist/utils/browser-command-argv.js.map +1 -1
  44. package/dist/utils/project-name.d.ts +2 -0
  45. package/dist/utils/project-name.d.ts.map +1 -1
  46. package/dist/utils/project-name.js +6 -0
  47. package/dist/utils/project-name.js.map +1 -1
  48. package/dist/utils/session.d.ts +14 -0
  49. package/dist/utils/session.d.ts.map +1 -0
  50. package/dist/utils/session.js +65 -0
  51. package/dist/utils/session.js.map +1 -0
  52. package/dist/utils/version-check.js +2 -2
  53. package/dist/utils/version-check.js.map +1 -1
  54. package/package.json +8 -18
  55. package/dist/commands/cloud-check-pr.d.ts +0 -9
  56. package/dist/commands/cloud-check-pr.d.ts.map +0 -1
  57. package/dist/commands/cloud-check-pr.js +0 -243
  58. package/dist/commands/cloud-check-pr.js.map +0 -1
  59. package/dist/commands/cloud-fix.d.ts +0 -13
  60. package/dist/commands/cloud-fix.d.ts.map +0 -1
  61. package/dist/commands/cloud-fix.js +0 -79
  62. package/dist/commands/cloud-fix.js.map +0 -1
  63. package/dist/commands/find-component.d.ts +0 -8
  64. package/dist/commands/find-component.d.ts.map +0 -1
  65. package/dist/commands/find-component.js +0 -182
  66. package/dist/commands/find-component.js.map +0 -1
  67. package/dist/skills/d3k/SKILL.md +0 -126
  68. package/dist/skills/index.d.ts +0 -46
  69. package/dist/skills/index.d.ts.map +0 -1
  70. package/dist/skills/index.js +0 -174
  71. package/dist/skills/index.js.map +0 -1
package/README.md CHANGED
@@ -62,9 +62,6 @@ d3k fix --time 30 # Analyze last 30 minutes (default: 10)
62
62
  d3k crawl # Discover URLs by crawling the app
63
63
  d3k crawl --depth all # Exhaustive crawl (default: 1 level)
64
64
 
65
- d3k find-component "nav.header" # Find React component source
66
- d3k find-component "[data-testid='button']"
67
-
68
65
  d3k restart # Restart the development server (rarely needed)
69
66
  ```
70
67
 
@@ -74,7 +71,6 @@ d3k restart # Restart the development server (rarely needed)
74
71
  d3k skill [name] # Get skill content or list available skills
75
72
  d3k upgrade # Upgrade d3k to the latest version
76
73
  d3k agent-browser # Run the bundled agent-browser CLI
77
- d3k cloud # Cloud-based tools using Vercel Sandbox
78
74
  ```
79
75
 
80
76
  ## Options
@@ -17,6 +17,8 @@ export interface CDPTargetInfo {
17
17
  url?: string;
18
18
  webSocketDebuggerUrl?: string;
19
19
  }
20
+ export declare const CHROME_CRASH_RESTORE_SUPPRESSION_FLAGS: string[];
21
+ export declare function resetChromeCrashRestoreState(profileDir: string): number;
20
22
  export declare function getLoadingHtmlCandidates(currentDir: string, execPath?: string): string[];
21
23
  export declare function selectCDPTarget(targets: CDPTargetInfo[], options?: {
22
24
  appServerPort?: string;
@@ -114,6 +116,7 @@ export declare class CDPMonitor {
114
116
  */
115
117
  prepareShutdown(): void;
116
118
  private waitForBrowserExit;
119
+ private sendBrowserCloseCommand;
117
120
  shutdown(): Promise<void>;
118
121
  private killInstanceChromeProcesses;
119
122
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cdp-monitor.d.ts","sourceRoot":"","sources":["../src/cdp-monitor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cdp-monitor.d.ts","sourceRoot":"","sources":["../src/cdp-monitor.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { spawn } from "child_process";
2
- import { existsSync, mkdtempSync, readFileSync, writeFileSync } from "fs";
2
+ import { existsSync, mkdtempSync, readdirSync, readFileSync, writeFileSync } from "fs";
3
3
  import { tmpdir } from "os";
4
4
  import { dirname, join } from "path";
5
5
  import { fileURLToPath } from "url";
@@ -45,6 +45,98 @@ const EMBEDDED_LOADING_HTML = `<!DOCTYPE html>
45
45
  </html>`;
46
46
  const DEFAULT_CDP_COMMAND_TIMEOUT_MS = 10000;
47
47
  const DEFAULT_NAVIGATION_TIMEOUT_MS = 60000;
48
+ export const CHROME_CRASH_RESTORE_SUPPRESSION_FLAGS = [
49
+ "--disable-session-crashed-bubble",
50
+ "--disable-restore-session-state",
51
+ "--hide-crash-restore-bubble"
52
+ ];
53
+ function isRecord(value) {
54
+ return typeof value === "object" && value !== null && !Array.isArray(value);
55
+ }
56
+ function patchChromePreferences(data) {
57
+ let changed = false;
58
+ const profile = isRecord(data.profile) ? data.profile : {};
59
+ if (data.profile !== profile) {
60
+ data.profile = profile;
61
+ changed = true;
62
+ }
63
+ if (profile.exit_type !== "Normal") {
64
+ profile.exit_type = "Normal";
65
+ changed = true;
66
+ }
67
+ if (profile.exited_cleanly !== true) {
68
+ profile.exited_cleanly = true;
69
+ changed = true;
70
+ }
71
+ return changed;
72
+ }
73
+ function patchChromeLocalState(data) {
74
+ let changed = false;
75
+ if (data.exit_type === "Crashed") {
76
+ data.exit_type = "Normal";
77
+ changed = true;
78
+ }
79
+ if (data.exited_cleanly === false) {
80
+ data.exited_cleanly = true;
81
+ changed = true;
82
+ }
83
+ if (isRecord(data.profile)) {
84
+ if (data.profile.exit_type === "Crashed") {
85
+ data.profile.exit_type = "Normal";
86
+ changed = true;
87
+ }
88
+ if (data.profile.exited_cleanly === false) {
89
+ data.profile.exited_cleanly = true;
90
+ changed = true;
91
+ }
92
+ }
93
+ return changed;
94
+ }
95
+ function patchJsonFile(filePath, patch) {
96
+ if (!existsSync(filePath)) {
97
+ return false;
98
+ }
99
+ try {
100
+ const data = JSON.parse(readFileSync(filePath, "utf-8"));
101
+ if (!isRecord(data) || !patch(data)) {
102
+ return false;
103
+ }
104
+ writeFileSync(filePath, JSON.stringify(data));
105
+ return true;
106
+ }
107
+ catch {
108
+ return false;
109
+ }
110
+ }
111
+ function getChromePreferencesFiles(profileDir) {
112
+ const files = new Set([join(profileDir, "Default", "Preferences")]);
113
+ if (!existsSync(profileDir)) {
114
+ return Array.from(files);
115
+ }
116
+ try {
117
+ for (const entry of readdirSync(profileDir, { withFileTypes: true })) {
118
+ if (entry.isDirectory() && (entry.name === "Default" || entry.name.startsWith("Profile "))) {
119
+ files.add(join(profileDir, entry.name, "Preferences"));
120
+ }
121
+ }
122
+ }
123
+ catch {
124
+ // Ignore unreadable profile directories.
125
+ }
126
+ return Array.from(files);
127
+ }
128
+ export function resetChromeCrashRestoreState(profileDir) {
129
+ let changedFiles = 0;
130
+ for (const preferencesFile of getChromePreferencesFiles(profileDir)) {
131
+ if (patchJsonFile(preferencesFile, patchChromePreferences)) {
132
+ changedFiles++;
133
+ }
134
+ }
135
+ if (patchJsonFile(join(profileDir, "Local State"), patchChromeLocalState)) {
136
+ changedFiles++;
137
+ }
138
+ return changedFiles;
139
+ }
48
140
  export function getLoadingHtmlCandidates(currentDir, execPath = process.execPath) {
49
141
  const candidates = [join(currentDir, "src/loading.html"), join(currentDir, "loading.html")];
50
142
  const packageRoot = dirname(dirname(execPath));
@@ -438,10 +530,21 @@ export class CDPMonitor {
438
530
  */
439
531
  async killExistingChromeWithProfile() {
440
532
  try {
441
- // Find Chrome processes using this profile directory
533
+ // Build a set of PIDs that must never be killed: this Node process and
534
+ // its parent. d3k's own argv contains the profile path (via --profile-dir),
535
+ // which previously caused a substring match here and made d3k SIGTERM itself.
536
+ const selfPids = new Set();
537
+ if (typeof process.pid === "number")
538
+ selfPids.add(process.pid);
539
+ if (typeof process.ppid === "number")
540
+ selfPids.add(process.ppid);
541
+ // Find Chrome processes using this profile directory. We only match the
542
+ // canonical `--user-data-dir=<profile>` form Chrome consumes; matching the
543
+ // bare path was too loose and caught unrelated processes (including d3k itself).
442
544
  const processes = await this.listProcesses();
443
545
  const pids = processes
444
- .filter((proc) => proc.command.includes(`--user-data-dir=${this.profileDir}`) || proc.command.includes(this.profileDir))
546
+ .filter((proc) => !selfPids.has(proc.pid))
547
+ .filter((proc) => proc.command.includes(`--user-data-dir=${this.profileDir}`))
445
548
  .map((proc) => proc.pid)
446
549
  .filter((pid) => pid !== this.browser?.pid);
447
550
  for (const pid of pids) {
@@ -465,6 +568,10 @@ export class CDPMonitor {
465
568
  async launchChrome() {
466
569
  // Kill any existing Chrome using this profile to prevent CDP conflicts
467
570
  await this.killExistingChromeWithProfile();
571
+ const resetProfileFiles = resetChromeCrashRestoreState(this.profileDir);
572
+ if (resetProfileFiles > 0) {
573
+ this.debugLog(`Reset Chrome crash restore state in ${resetProfileFiles} profile file(s)`);
574
+ }
468
575
  return new Promise((resolve, reject) => {
469
576
  // Use custom browser path if provided, otherwise try different Chrome executables based on platform
470
577
  const chromeCommands = this.browserPath
@@ -474,6 +581,8 @@ export class CDPMonitor {
474
581
  "google-chrome",
475
582
  "chrome",
476
583
  "chromium",
584
+ "brave",
585
+ "brave-browser",
477
586
  "/Applications/Arc.app/Contents/MacOS/Arc",
478
587
  "/Applications/Comet.app/Contents/MacOS/Comet",
479
588
  "/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge"
@@ -513,8 +622,7 @@ export class CDPMonitor {
513
622
  "--disable-sync",
514
623
  "--metrics-recording-only",
515
624
  "--disable-default-apps",
516
- "--disable-session-crashed-bubble",
517
- "--disable-restore-session-state"
625
+ ...CHROME_CRASH_RESTORE_SUPPRESSION_FLAGS
518
626
  ];
519
627
  if (shouldEnableReactDevTools && reactDevToolsExtensionPath) {
520
628
  chromeArgs.push(`--disable-extensions-except=${reactDevToolsExtensionPath}`);
@@ -1774,49 +1882,128 @@ export class CDPMonitor {
1774
1882
  browser.once("exit", onExit);
1775
1883
  });
1776
1884
  }
1885
+ async sendBrowserCloseCommand() {
1886
+ try {
1887
+ await this.sendCDPCommand("Browser.close", {}, 3000);
1888
+ this.debugLog("Sent Browser.close command");
1889
+ return;
1890
+ }
1891
+ catch (error) {
1892
+ this.debugLog(`Browser.close on page target failed: ${error}`);
1893
+ }
1894
+ const versionResponse = await fetch(`http://localhost:${this.debugPort}/json/version`, {
1895
+ signal: AbortSignal.timeout(1000)
1896
+ });
1897
+ if (!versionResponse.ok) {
1898
+ throw new Error(`Failed to get browser CDP endpoint: HTTP ${versionResponse.status}`);
1899
+ }
1900
+ const version = (await versionResponse.json());
1901
+ if (!version.webSocketDebuggerUrl) {
1902
+ throw new Error("Browser CDP endpoint did not include webSocketDebuggerUrl");
1903
+ }
1904
+ await new Promise((resolve, reject) => {
1905
+ const ws = new WebSocket(version.webSocketDebuggerUrl);
1906
+ let commandSent = false;
1907
+ let settled = false;
1908
+ const settle = (callback) => {
1909
+ if (settled)
1910
+ return;
1911
+ settled = true;
1912
+ clearTimeout(timeout);
1913
+ try {
1914
+ ws.close();
1915
+ }
1916
+ catch {
1917
+ // Ignore close errors.
1918
+ }
1919
+ callback();
1920
+ };
1921
+ const timeout = setTimeout(() => {
1922
+ settle(() => reject(new Error("Browser.close command timed out")));
1923
+ }, 3000);
1924
+ ws.on("open", () => {
1925
+ commandSent = true;
1926
+ ws.send(JSON.stringify({ id: 1, method: "Browser.close", params: {} }), (error) => {
1927
+ if (error) {
1928
+ settle(() => reject(error));
1929
+ }
1930
+ });
1931
+ });
1932
+ ws.on("message", (data) => {
1933
+ try {
1934
+ const message = JSON.parse(data.toString());
1935
+ if (message.id !== 1) {
1936
+ return;
1937
+ }
1938
+ const responseError = message.error;
1939
+ if (responseError) {
1940
+ settle(() => reject(new Error(responseError.message || "Browser.close failed")));
1941
+ return;
1942
+ }
1943
+ settle(resolve);
1944
+ }
1945
+ catch (error) {
1946
+ settle(() => reject(error instanceof Error ? error : new Error(String(error))));
1947
+ }
1948
+ });
1949
+ ws.on("error", (error) => {
1950
+ settle(() => reject(error));
1951
+ });
1952
+ ws.on("close", () => {
1953
+ if (commandSent) {
1954
+ settle(resolve);
1955
+ }
1956
+ else {
1957
+ settle(() => reject(new Error("Browser CDP websocket closed before Browser.close was sent")));
1958
+ }
1959
+ });
1960
+ });
1961
+ this.debugLog("Sent Browser.close command via browser CDP endpoint");
1962
+ }
1777
1963
  async shutdown() {
1778
1964
  this.isShuttingDown = true;
1779
1965
  let browserClosedCleanly = false;
1780
1966
  // Ask the browser process to exit first so Chrome doesn't think it crashed.
1781
- if (this.connection?.sessionId) {
1967
+ if (this.connection) {
1782
1968
  try {
1783
- await this.sendCDPCommand("Browser.close");
1784
- this.debugLog("Sent Browser.close command");
1785
- browserClosedCleanly = await this.waitForBrowserExit(2000);
1969
+ await this.sendBrowserCloseCommand();
1970
+ browserClosedCleanly = await this.waitForBrowserExit(5000);
1786
1971
  }
1787
1972
  catch (_e) {
1788
1973
  this.debugLog("Browser.close failed, trying page/tab close fallback");
1789
1974
  }
1790
- try {
1791
- // Try to close the page
1792
- await this.sendCDPCommand("Page.close");
1793
- this.debugLog("Sent Page.close command");
1794
- await new Promise((resolve) => setTimeout(resolve, 100));
1795
- }
1796
- catch (_e) {
1797
- this.debugLog("Page.close failed, trying Target.closeTarget");
1798
- }
1799
- try {
1800
- // Get the list of targets to find our specific tab
1801
- const targets = (await this.sendCDPCommand("Target.getTargets"));
1802
- this.debugLog(`Found ${targets.targetInfos?.length || 0} targets`);
1803
- // Find our page target
1804
- const pageTarget = targets.targetInfos?.find((t) => t.type === "page");
1805
- if (pageTarget) {
1806
- this.debugLog(`Closing page target: ${pageTarget.targetId}`);
1807
- await this.sendCDPCommand("Target.closeTarget", {
1808
- targetId: pageTarget.targetId
1809
- });
1810
- this.debugLog("Closed Chrome tab via CDP");
1811
- }
1812
- // Give it more time for the tab to close
1813
- await new Promise((resolve) => setTimeout(resolve, 1000));
1814
- }
1815
- catch (_e) {
1816
- this.debugLog("Failed to close tab via CDP, will force close Chrome");
1817
- }
1818
1975
  if (!browserClosedCleanly) {
1819
- browserClosedCleanly = await this.waitForBrowserExit(1500);
1976
+ try {
1977
+ // Try to close the page
1978
+ await this.sendCDPCommand("Page.close");
1979
+ this.debugLog("Sent Page.close command");
1980
+ await new Promise((resolve) => setTimeout(resolve, 100));
1981
+ }
1982
+ catch (_e) {
1983
+ this.debugLog("Page.close failed, trying Target.closeTarget");
1984
+ }
1985
+ try {
1986
+ // Get the list of targets to find our specific tab
1987
+ const targets = (await this.sendCDPCommand("Target.getTargets"));
1988
+ this.debugLog(`Found ${targets.targetInfos?.length || 0} targets`);
1989
+ // Find our page target
1990
+ const pageTarget = targets.targetInfos?.find((t) => t.type === "page");
1991
+ if (pageTarget) {
1992
+ this.debugLog(`Closing page target: ${pageTarget.targetId}`);
1993
+ await this.sendCDPCommand("Target.closeTarget", {
1994
+ targetId: pageTarget.targetId
1995
+ });
1996
+ this.debugLog("Closed Chrome tab via CDP");
1997
+ }
1998
+ // Give it more time for the tab to close
1999
+ await new Promise((resolve) => setTimeout(resolve, 1000));
2000
+ }
2001
+ catch (_e) {
2002
+ this.debugLog("Failed to close tab via CDP, will force close Chrome");
2003
+ }
2004
+ if (!browserClosedCleanly) {
2005
+ browserClosedCleanly = await this.waitForBrowserExit(1500);
2006
+ }
1820
2007
  }
1821
2008
  }
1822
2009
  // Close CDP connection