devharness 0.8.0 → 0.9.0

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 (105) hide show
  1. package/README.md +12 -0
  2. package/build/cdp-manager.js +1 -1
  3. package/build/cdp-manager.js.map +1 -1
  4. package/build/chrome-launcher.d.ts +7 -7
  5. package/build/chrome-launcher.d.ts.map +1 -1
  6. package/build/chrome-launcher.js +9 -8
  7. package/build/chrome-launcher.js.map +1 -1
  8. package/build/command-recorder.d.ts +1 -1
  9. package/build/command-recorder.js +1 -1
  10. package/build/config.d.ts +5 -5
  11. package/build/config.js +15 -15
  12. package/build/config.js.map +1 -1
  13. package/build/config.test.js +4 -4
  14. package/build/config.test.js.map +1 -1
  15. package/build/dashboard/dashboard-client.js +2 -2
  16. package/build/dashboard/dashboard-client.js.map +1 -1
  17. package/build/dashboard/dashboard-hub.js +3 -2
  18. package/build/dashboard/dashboard-hub.js.map +1 -1
  19. package/build/debug-logger.d.ts +1 -1
  20. package/build/debug-logger.js +1 -1
  21. package/build/helpers/parser-plugins.d.ts +2 -2
  22. package/build/helpers/parser-plugins.js +2 -2
  23. package/build/helpers/paths-migration.test.d.ts +2 -0
  24. package/build/helpers/paths-migration.test.d.ts.map +1 -0
  25. package/build/helpers/paths-migration.test.js +65 -0
  26. package/build/helpers/paths-migration.test.js.map +1 -0
  27. package/build/helpers/paths.d.ts +28 -9
  28. package/build/helpers/paths.d.ts.map +1 -1
  29. package/build/helpers/paths.js +66 -16
  30. package/build/helpers/paths.js.map +1 -1
  31. package/build/index.js +46 -46
  32. package/build/index.js.map +1 -1
  33. package/build/interaction-recorder.js +4 -4
  34. package/build/interaction-recorder.js.map +1 -1
  35. package/build/issue-tracker.js +4 -4
  36. package/build/issue-tracker.js.map +1 -1
  37. package/build/issue-tracker.test.js +1 -1
  38. package/build/issue-tracker.test.js.map +1 -1
  39. package/build/log-processor/orchestrator.d.ts +2 -2
  40. package/build/log-processor/orchestrator.d.ts.map +1 -1
  41. package/build/log-processor/orchestrator.js +1 -1
  42. package/build/mcp-supervisor.js +2 -3
  43. package/build/mcp-supervisor.js.map +1 -1
  44. package/build/messages.d.ts +1 -1
  45. package/build/messages.js +3 -3
  46. package/build/messages.js.map +1 -1
  47. package/build/overlays.d.ts +1 -1
  48. package/build/overlays.js +2 -2
  49. package/build/overlays.js.map +1 -1
  50. package/build/persistent-profiles.test.js +5 -5
  51. package/build/persistent-profiles.test.js.map +1 -1
  52. package/build/runners/types.d.ts +1 -1
  53. package/build/runners/types.d.ts.map +1 -1
  54. package/build/self-restart.js +1 -1
  55. package/build/server-claims.js +2 -2
  56. package/build/server-claims.js.map +1 -1
  57. package/build/server-claims.test.js +3 -3
  58. package/build/server-claims.test.js.map +1 -1
  59. package/build/server-manager.d.ts +4 -4
  60. package/build/server-manager.d.ts.map +1 -1
  61. package/build/server-manager.js +7 -7
  62. package/build/server-manager.js.map +1 -1
  63. package/build/server-ownership.test.js +2 -2
  64. package/build/server-ownership.test.js.map +1 -1
  65. package/build/server-watcher.js +2 -2
  66. package/build/server-watcher.js.map +1 -1
  67. package/build/supervisor/idle-config.d.ts +1 -1
  68. package/build/supervisor/idle-config.d.ts.map +1 -1
  69. package/build/supervisor/idle-config.js +1 -1
  70. package/build/tools/breakpoint-tools.js +1 -1
  71. package/build/tools/breakpoint-tools.js.map +1 -1
  72. package/build/tools/config-tools.js +2 -2
  73. package/build/tools/config-tools.js.map +1 -1
  74. package/build/tools/console-tools.js +1 -1
  75. package/build/tools/console-tools.js.map +1 -1
  76. package/build/tools/content-tools.js +5 -5
  77. package/build/tools/content-tools.js.map +1 -1
  78. package/build/tools/replay-add-conditional.test.js +2 -2
  79. package/build/tools/replay-add-conditional.test.js.map +1 -1
  80. package/build/tools/replay-folder-save.test.js +1 -1
  81. package/build/tools/replay-folder-save.test.js.map +1 -1
  82. package/build/tools/replay-formatters.d.ts +1 -1
  83. package/build/tools/replay-formatters.js +1 -1
  84. package/build/tools/replay-tools.js +4 -4
  85. package/build/tools/replay-tools.js.map +1 -1
  86. package/build/tools/screenshot-tools.js +1 -1
  87. package/build/tools/screenshot-tools.js.map +1 -1
  88. package/build/tools/server-tools.js +1 -1
  89. package/build/tools/server-tools.js.map +1 -1
  90. package/build/tools/storage-tools.js +1 -1
  91. package/build/tools/storage-tools.js.map +1 -1
  92. package/docs/automation.md +3 -3
  93. package/docs/installation.md +3 -3
  94. package/docs/instructions.md +7 -7
  95. package/docs/mcp-instructions.md +3 -3
  96. package/docs/messages.md +5 -5
  97. package/docs/parser-plugins.md +4 -4
  98. package/docs/replay.md +11 -11
  99. package/docs/troubleshooting.md +2 -2
  100. package/package.json +1 -1
  101. package/skills/devharness/SKILL.md +3 -3
  102. package/build/session-detector.test.d.ts +0 -9
  103. package/build/session-detector.test.d.ts.map +0 -1
  104. package/build/session-detector.test.js +0 -45
  105. package/build/session-detector.test.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths-migration.test.js","sourceRoot":"","sources":["../../src/helpers/paths-migration.test.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,30 @@
1
1
  /**
2
- * Centralized path configuration for cdp-tools output directories
2
+ * Centralized path configuration for devharness output directories
3
3
  *
4
- * All data defaults to working directory (<cwd>/.cdp-tools/).
5
- * Use global: true to save to ~/.cdp-tools/ instead.
4
+ * All data defaults to working directory (<cwd>/.devharness/).
5
+ * Use global: true to save to ~/.devharness/ instead.
6
6
  * If cwd is invalid (e.g., "/"), falls back to global automatically.
7
+ *
8
+ * The directory was `.cdp-tools` before the rename in 0.9.0 and holds things
9
+ * users would miss: persistent Chrome profiles (logins, IndexedDB), config,
10
+ * recorded sequences, issues. So this migrates rather than switches - see
11
+ * resolveStateDir.
7
12
  */
8
13
  import { z } from 'zod';
14
+ /**
15
+ * The state directory under `parent`, migrating a legacy `.cdp-tools` into
16
+ * place if that is what exists.
17
+ *
18
+ * Rename, not copy: it is atomic within a filesystem, so there is no window
19
+ * where half the profiles are in one directory and half in the other. If it
20
+ * fails for any reason - cross-device, permissions, a directory held open on
21
+ * Windows - keep using the legacy directory for this session rather than
22
+ * starting a fresh empty one. A user whose saved logins silently vanished
23
+ * would have no way to connect the two events.
24
+ */
25
+ export declare function resolveStateDir(parent: string): string;
26
+ /** Global state directory, migrated if needed. */
27
+ export declare function getGlobalBase(): string;
9
28
  declare const pathOptionsSchema: z.ZodObject<{
10
29
  global: z.ZodOptional<z.ZodBoolean>;
11
30
  }, "strict", z.ZodTypeAny, {
@@ -33,12 +52,12 @@ export declare function initializePaths(): PathConfig;
33
52
  */
34
53
  export declare function setWorkingDirOverride(dir: string): void;
35
54
  /**
36
- * Get path for cdp-tools data.
37
- * Defaults to working directory, use global: true for ~/.cdp-tools/
55
+ * Get path for devharness data.
56
+ * Defaults to working directory, use global: true for ~/.devharness/
38
57
  *
39
58
  * @param segments - Path segments to join (e.g., 'logs', 'debug.log')
40
- * @param options - { global: true } to use ~/.cdp-tools/ instead of cwd
41
- * @returns Full path like /project/.cdp-tools/logs/debug.log
59
+ * @param options - { global: true } to use ~/.devharness/ instead of cwd
60
+ * @returns Full path like /project/.devharness/logs/debug.log
42
61
  */
43
62
  export declare function getOutputPath(...args: [...string[]] | [...string[], z.infer<typeof pathOptionsSchema>]): string;
44
63
  /**
@@ -51,7 +70,7 @@ export declare function getConfigPath(): string;
51
70
  /**
52
71
  * Get path for saving new config.
53
72
  *
54
- * @param options - { global: true } to save to ~/.cdp-tools/ (default: working directory)
73
+ * @param options - { global: true } to save to ~/.devharness/ (default: working directory)
55
74
  * @returns Path to config.json
56
75
  */
57
76
  export declare function getConfigSavePath(options?: {
@@ -62,7 +81,7 @@ export declare function getConfigSavePath(options?: {
62
81
  * Uses system temp directory.
63
82
  *
64
83
  * @param segments - Path segments to join (e.g., 'a4-page.css')
65
- * @returns Full path like /tmp/cdp-tools/a4-page.css
84
+ * @returns Full path like /tmp/devharness/a4-page.css
66
85
  */
67
86
  export declare function getTempPath(...segments: string[]): string;
68
87
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/helpers/paths.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,QAAA,MAAM,iBAAiB;;;;;;EAEZ,CAAC;AAEZ,UAAU,UAAU;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAsBD;;;GAGG;AACH,wBAAgB,eAAe,IAAI,UAAU,CAW5C;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAMvD;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,GAAG,IAAI,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC,GACxE,MAAM,CA0BR;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAatC;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAUxE;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAGzD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAG9C;AAGD,sCAAsC;AACtC,wBAAgB,iBAAiB,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAE/D;AAED,mEAAmE;AACnE,wBAAgB,aAAa,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAE3D;AAED,sCAAsC;AACtC,eAAO,MAAM,iBAAiB,sBAAgB,CAAC"}
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/helpers/paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAyBtD;AAED,kDAAkD;AAClD,wBAAgB,aAAa,IAAI,MAAM,CAItC;AAED,QAAA,MAAM,iBAAiB;;;;;;EAEZ,CAAC;AAEZ,UAAU,UAAU;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAsBD;;;GAGG;AACH,wBAAgB,eAAe,IAAI,UAAU,CAW5C;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAMvD;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,GAAG,IAAI,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC,GACxE,MAAM,CA0BR;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAatC;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAUxE;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAGzD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAG9C;AAGD,sCAAsC;AACtC,wBAAgB,iBAAiB,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAE/D;AAED,mEAAmE;AACnE,wBAAgB,aAAa,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAE3D;AAED,sCAAsC;AACtC,eAAO,MAAM,iBAAiB,sBAAgB,CAAC"}
@@ -1,15 +1,65 @@
1
1
  /**
2
- * Centralized path configuration for cdp-tools output directories
2
+ * Centralized path configuration for devharness output directories
3
3
  *
4
- * All data defaults to working directory (<cwd>/.cdp-tools/).
5
- * Use global: true to save to ~/.cdp-tools/ instead.
4
+ * All data defaults to working directory (<cwd>/.devharness/).
5
+ * Use global: true to save to ~/.devharness/ instead.
6
6
  * If cwd is invalid (e.g., "/"), falls back to global automatically.
7
+ *
8
+ * The directory was `.cdp-tools` before the rename in 0.9.0 and holds things
9
+ * users would miss: persistent Chrome profiles (logins, IndexedDB), config,
10
+ * recorded sequences, issues. So this migrates rather than switches - see
11
+ * resolveStateDir.
7
12
  */
8
13
  import { join } from 'path';
9
14
  import { homedir, tmpdir } from 'os';
10
- import { existsSync, accessSync, constants } from 'fs';
15
+ import { existsSync, accessSync, constants, renameSync } from 'fs';
11
16
  import { z } from 'zod';
12
- const OUTPUT_DIR = '.cdp-tools';
17
+ const OUTPUT_DIR = '.devharness';
18
+ const LEGACY_OUTPUT_DIR = '.cdp-tools';
19
+ /** Migration is announced once per process, not once per path lookup. */
20
+ let migrationLogged = false;
21
+ /**
22
+ * The state directory under `parent`, migrating a legacy `.cdp-tools` into
23
+ * place if that is what exists.
24
+ *
25
+ * Rename, not copy: it is atomic within a filesystem, so there is no window
26
+ * where half the profiles are in one directory and half in the other. If it
27
+ * fails for any reason - cross-device, permissions, a directory held open on
28
+ * Windows - keep using the legacy directory for this session rather than
29
+ * starting a fresh empty one. A user whose saved logins silently vanished
30
+ * would have no way to connect the two events.
31
+ */
32
+ export function resolveStateDir(parent) {
33
+ const current = join(parent, OUTPUT_DIR);
34
+ const legacy = join(parent, LEGACY_OUTPUT_DIR);
35
+ if (existsSync(current))
36
+ return current;
37
+ if (!existsSync(legacy))
38
+ return current;
39
+ try {
40
+ renameSync(legacy, current);
41
+ if (!migrationLogged) {
42
+ console.error(`[devharness] migrated ${legacy} -> ${current}`);
43
+ migrationLogged = true;
44
+ }
45
+ return current;
46
+ }
47
+ catch (error) {
48
+ if (!migrationLogged) {
49
+ console.error(`[devharness] could not migrate ${legacy} to ${current} ` +
50
+ `(${error instanceof Error ? error.message : String(error)}); ` +
51
+ `continuing to use ${legacy}`);
52
+ migrationLogged = true;
53
+ }
54
+ return legacy;
55
+ }
56
+ }
57
+ /** Global state directory, migrated if needed. */
58
+ export function getGlobalBase() {
59
+ return process.env.DEVHARNESS_DIR
60
+ || process.env.CDP_TOOLS_DIR // pre-0.9.0 name, still honoured
61
+ || resolveStateDir(homedir());
62
+ }
13
63
  const pathOptionsSchema = z.object({
14
64
  global: z.boolean().optional(),
15
65
  }).strict();
@@ -39,13 +89,13 @@ function isValidWorkingDirectory(dir) {
39
89
  * Called automatically on first path request, but can be called explicitly for early initialization.
40
90
  */
41
91
  export function initializePaths() {
42
- const envOverride = process.env.CDP_TOOLS_DIR;
43
- const globalBase = envOverride || join(homedir(), OUTPUT_DIR);
92
+ const globalBase = getGlobalBase();
44
93
  const cwd = process.cwd();
45
94
  const workingDirBase = isValidWorkingDirectory(cwd)
46
- ? join(cwd, OUTPUT_DIR)
95
+ ? resolveStateDir(cwd)
47
96
  : null;
48
- const tempBase = join(tmpdir(), 'cdp-tools');
97
+ // Ephemeral, so it gets the new name outright with nothing to migrate.
98
+ const tempBase = join(tmpdir(), 'devharness');
49
99
  pathConfig = { globalBase, workingDirBase, tempBase };
50
100
  return pathConfig;
51
101
  }
@@ -63,15 +113,15 @@ export function setWorkingDirOverride(dir) {
63
113
  }
64
114
  if (!pathConfig)
65
115
  initializePaths();
66
- pathConfig.workingDirBase = join(dir, OUTPUT_DIR);
116
+ pathConfig.workingDirBase = resolveStateDir(dir);
67
117
  }
68
118
  /**
69
- * Get path for cdp-tools data.
70
- * Defaults to working directory, use global: true for ~/.cdp-tools/
119
+ * Get path for devharness data.
120
+ * Defaults to working directory, use global: true for ~/.devharness/
71
121
  *
72
122
  * @param segments - Path segments to join (e.g., 'logs', 'debug.log')
73
- * @param options - { global: true } to use ~/.cdp-tools/ instead of cwd
74
- * @returns Full path like /project/.cdp-tools/logs/debug.log
123
+ * @param options - { global: true } to use ~/.devharness/ instead of cwd
124
+ * @returns Full path like /project/.devharness/logs/debug.log
75
125
  */
76
126
  export function getOutputPath(...args) {
77
127
  if (!pathConfig)
@@ -121,7 +171,7 @@ export function getConfigPath() {
121
171
  /**
122
172
  * Get path for saving new config.
123
173
  *
124
- * @param options - { global: true } to save to ~/.cdp-tools/ (default: working directory)
174
+ * @param options - { global: true } to save to ~/.devharness/ (default: working directory)
125
175
  * @returns Path to config.json
126
176
  */
127
177
  export function getConfigSavePath(options) {
@@ -139,7 +189,7 @@ export function getConfigSavePath(options) {
139
189
  * Uses system temp directory.
140
190
  *
141
191
  * @param segments - Path segments to join (e.g., 'a4-page.css')
142
- * @returns Full path like /tmp/cdp-tools/a4-page.css
192
+ * @returns Full path like /tmp/devharness/a4-page.css
143
193
  */
144
194
  export function getTempPath(...segments) {
145
195
  if (!pathConfig)
@@ -1 +1 @@
1
- {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/helpers/paths.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/helpers/paths.ts"],"names":[],"mappings":"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"}
package/build/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  // Early stderr logging for debugging startup issues
3
- console.error(`[cdp-tools] Process starting (PID: ${process.pid})`);
3
+ console.error(`[devharness] Process starting (PID: ${process.pid})`);
4
4
  // Capture startup time immediately before any imports
5
5
  const STARTUP_TIME = performance.now();
6
6
  /**
@@ -63,7 +63,7 @@ import { join, dirname } from 'path';
63
63
  import { fileURLToPath } from 'url';
64
64
  import { debugLog, enableDebugLogging, disableDebugLogging, isDebugEnabled, enableHistoryLogging, setStartupMetrics } from './debug-logger.js';
65
65
  import { validateReference, requireValidReference, deriveConnectionReference, UNNAMED_CONNECTION, InvalidReferenceError } from './reference-validator.js';
66
- import { initializePaths } from './helpers/paths.js';
66
+ import { initializePaths, resolveStateDir } from './helpers/paths.js';
67
67
  import { cleanupStaleTempFiles, cleanupStaleTempFilesSync } from './atomic-write.js';
68
68
  import { createSessionDetector } from './session-detector.js';
69
69
  import { serverClaims } from './server-claims.js';
@@ -114,13 +114,13 @@ async function findAvailablePort(startPort) {
114
114
  // Explicitly bind to IPv4 localhost to match Chrome's behavior
115
115
  server.listen(startPort, '127.0.0.1', () => {
116
116
  const port = server.address().port;
117
- console.error(`[cdp-tools] findAvailablePort: Port ${port} is available`);
117
+ console.error(`[devharness] findAvailablePort: Port ${port} is available`);
118
118
  server.close(() => resolve(port));
119
119
  });
120
120
  server.on('error', (err) => {
121
121
  if (err.code === 'EADDRINUSE') {
122
122
  // Port in use, try next one
123
- console.error(`[cdp-tools] findAvailablePort: Port ${startPort} is in use, trying ${startPort + 1}`);
123
+ console.error(`[devharness] findAvailablePort: Port ${startPort} is in use, trying ${startPort + 1}`);
124
124
  resolve(findAvailablePort(startPort + 1));
125
125
  }
126
126
  else {
@@ -228,7 +228,7 @@ async function loadInstructions() {
228
228
  return instructions + nudge;
229
229
  }
230
230
  catch (error) {
231
- console.error('[cdp-tools] Failed to load instructions file:', error instanceof Error ? error.message : error);
231
+ console.error('[devharness] Failed to load instructions file:', error instanceof Error ? error.message : error);
232
232
  return undefined;
233
233
  }
234
234
  }
@@ -236,7 +236,7 @@ async function loadInstructions() {
236
236
  const sourceMapHandler = new SourceMapHandler();
237
237
  const chromeLauncher = new ChromeLauncher({
238
238
  // Resolved lazily so a live config reload of chrome.persistentProfileRoot
239
- // (global ~/.cdp-tools/profiles by default, or a project-local override)
239
+ // (global ~/.devharness/profiles by default, or a project-local override)
240
240
  // is picked up without restarting the server.
241
241
  persistentProfileRoot: () => configManager.getPersistentProfileRoot(),
242
242
  });
@@ -377,7 +377,7 @@ const connectionTools = {
377
377
  reference: z.string().optional().describe('Connection reference name (3 descriptive words). If not provided, defaults to "unnamed-connection-default". Use this to identify the connection when calling other tools.'),
378
378
  width: z.number().optional().describe('Viewport width in CSS px. Sizes the real OS window, not an emulated viewport, so the page keeps tracking window resizes. Bigger than the display is clamped and reported. Headless emulates instead.'),
379
379
  height: z.number().optional().describe('Viewport height in CSS px. Sized like `width`.'),
380
- profile: z.string().optional().describe('Named persistent Chrome profile, e.g. "device-a". Naming a profile makes it persistent: it maps to a stable user-data-dir under ~/.cdp-tools/profiles (override per project with chrome.persistentProfileRoot) and is never deleted, so cookies, localStorage and IndexedDB - including non-extractable CryptoKeys - survive across runs. Created on first use. Does NOT pin a port; port selection is unchanged. Wipe it with config({action:"resetProfile", profile:"device-a"}). Only one live Chrome may hold a given profile at a time.'),
380
+ profile: z.string().optional().describe('Named persistent Chrome profile, e.g. "device-a". Naming a profile makes it persistent: it maps to a stable user-data-dir under ~/.devharness/profiles (override per project with chrome.persistentProfileRoot) and is never deleted, so cookies, localStorage and IndexedDB - including non-extractable CryptoKeys - survive across runs. Created on first use. Does NOT pin a port; port selection is unchanged. Wipe it with config({action:"resetProfile", profile:"device-a"}). Only one live Chrome may hold a given profile at a time.'),
381
381
  chromeArgs: z.array(z.string()).optional().describe('Extra Chrome command-line flags to pass through at launch, e.g. ["--use-fake-device-for-media-stream", "--use-fake-ui-for-media-stream"]. Merged after the managed defaults. The CDP_TOOLS_EXTRA_CHROME_ARGS env var (space-separated) is also always merged. Only applies when this call actually launches Chrome (ignored when an existing instance on the port is reused).'),
382
382
  }).strict(), async (args) => {
383
383
  // Validate reference FIRST, before launching Chrome
@@ -653,7 +653,7 @@ const connectionTools = {
653
653
  await new Promise(resolve => setTimeout(resolve, 500));
654
654
  }
655
655
  catch (reloadError) {
656
- console.error(`[cdp-tools] Warning: Page reload failed: ${reloadError.message}`);
656
+ console.error(`[devharness] Warning: Page reload failed: ${reloadError.message}`);
657
657
  }
658
658
  }
659
659
  }
@@ -782,7 +782,7 @@ const connectionTools = {
782
782
  reason: z.string().describe('Why Chrome launcher needs to be reset'),
783
783
  }).strict(), async (args) => {
784
784
  // Log the reason for audit purposes
785
- console.error(`[cdp-tools] resetChromeLauncher called - Reason: ${args.reason}`);
785
+ console.error(`[devharness] resetChromeLauncher called - Reason: ${args.reason}`);
786
786
  chromeLauncher.reset();
787
787
  return createSuccessResponse('CHROME_LAUNCHER_RESET');
788
788
  }),
@@ -805,10 +805,10 @@ const connectionTools = {
805
805
  if (args.enabled) {
806
806
  await enableDebugLogging(); // Now async to log startup metrics
807
807
  return createSuccessResponse('DEBUG_LOGGING_ENABLED', {
808
- message: 'Debug logging enabled. Logs will be written to .cdp-tools/logs/debug.log'
808
+ message: 'Debug logging enabled. Logs will be written to .devharness/logs/debug.log'
809
809
  }, {
810
810
  enabled: true,
811
- message: 'Debug logging enabled. Logs will be written to .cdp-tools/logs/debug.log'
811
+ message: 'Debug logging enabled. Logs will be written to .devharness/logs/debug.log'
812
812
  });
813
813
  }
814
814
  else {
@@ -826,10 +826,10 @@ const connectionTools = {
826
826
  return createSuccessResponse('DEBUG_LOGGING_STATUS', {
827
827
  status: enabled ? 'enabled' : 'disabled',
828
828
  enabled, // Pass boolean for conditionals
829
- logFile: '.cdp-tools/logs/debug.log'
829
+ logFile: '.devharness/logs/debug.log'
830
830
  }, {
831
831
  enabled,
832
- logFile: '.cdp-tools/logs/debug.log'
832
+ logFile: '.devharness/logs/debug.log'
833
833
  });
834
834
  }),
835
835
  connectDebugger: createTool('Connect to debugger', z.object({
@@ -923,7 +923,7 @@ const connectionTools = {
923
923
  }
924
924
  catch (reloadError) {
925
925
  // Log warning but don't fail - page might already be loaded
926
- console.error(`[cdp-tools] Warning: Page reload failed: ${reloadError.message}`);
926
+ console.error(`[devharness] Warning: Page reload failed: ${reloadError.message}`);
927
927
  }
928
928
  }
929
929
  features.push('browser-automation', 'console-monitoring', 'network-monitoring');
@@ -1002,7 +1002,7 @@ const connectionTools = {
1002
1002
  reference: z.string().describe('3 descriptive words of the connection to disconnect'),
1003
1003
  }).strict(), async (args) => {
1004
1004
  // Log the reason for audit purposes
1005
- console.error(`[cdp-tools] disconnectDebugger called - Reason: ${args.reason}, Reference: ${args.reference}`);
1005
+ console.error(`[devharness] disconnectDebugger called - Reason: ${args.reason}, Reference: ${args.reference}`);
1006
1006
  // Find connection by reference
1007
1007
  const connection = connectionManager.findConnectionByReference(args.reference);
1008
1008
  if (!connection) {
@@ -1327,7 +1327,7 @@ function registerToolHandlers(server) {
1327
1327
  // Check for tool dependency conflicts (blocks ALL tools except config)
1328
1328
  if (toolName !== 'config' && configManager.hasDependencyConflicts()) {
1329
1329
  const conflicts = configManager.getDependencyConflicts();
1330
- const configPath = configManager.getStatus().loadedFrom || '.cdp-tools/config.json';
1330
+ const configPath = configManager.getStatus().loadedFrom || '.devharness/config.json';
1331
1331
  return {
1332
1332
  content: [
1333
1333
  {
@@ -1549,7 +1549,7 @@ async function runCliSequence(argv) {
1549
1549
  catch {
1550
1550
  attempts++;
1551
1551
  if (attempts >= maxAttempts) {
1552
- console.error(`[cdp-tools] Failed to reserve a port after ${maxAttempts} attempts`);
1552
+ console.error(`[devharness] Failed to reserve a port after ${maxAttempts} attempts`);
1553
1553
  process.exit(1);
1554
1554
  }
1555
1555
  process.env.MCP_DEBUG_PORT = String(port + 1);
@@ -1595,10 +1595,10 @@ async function main() {
1595
1595
  await runCliSequence(process.argv.slice(3));
1596
1596
  return;
1597
1597
  }
1598
- console.error(`[cdp-tools] main() called (PID: ${process.pid})`);
1598
+ console.error(`[devharness] main() called (PID: ${process.pid})`);
1599
1599
  // Initialize path configuration early (before any file operations)
1600
1600
  const pathConfig = initializePaths();
1601
- console.error(`[cdp-tools] Path config: global=${pathConfig.globalBase}, workingDir=${pathConfig.workingDirBase ?? 'none (using global fallback)'}`);
1601
+ console.error(`[devharness] Path config: global=${pathConfig.globalBase}, workingDir=${pathConfig.workingDirBase ?? 'none (using global fallback)'}`);
1602
1602
  // Clean up stale temp files from previous crashed/killed processes
1603
1603
  // Run in background - don't block startup
1604
1604
  Promise.all([
@@ -1607,7 +1607,7 @@ async function main() {
1607
1607
  ]).then(([globalResult, localResult]) => {
1608
1608
  const totalCleaned = globalResult.cleaned.length + localResult.cleaned.length;
1609
1609
  if (totalCleaned > 0) {
1610
- console.error(`[cdp-tools] Cleaned ${totalCleaned} stale temp file(s)`);
1610
+ console.error(`[devharness] Cleaned ${totalCleaned} stale temp file(s)`);
1611
1611
  }
1612
1612
  }).catch(() => {
1613
1613
  // Ignore cleanup errors - best effort only
@@ -1642,7 +1642,7 @@ async function main() {
1642
1642
  if (orchestratorInstance || !sessionDetectorInstance)
1643
1643
  return;
1644
1644
  try {
1645
- const configDir = join(cwd, '.cdp-tools', 'config');
1645
+ const configDir = join(resolveStateDir(cwd), 'config');
1646
1646
  mkdirSync(join(configDir, 'classifiers'), { recursive: true });
1647
1647
  mkdirSync(join(configDir, 'extractors'), { recursive: true });
1648
1648
  mkdirSync(join(configDir, 'state-machines'), { recursive: true });
@@ -1747,14 +1747,14 @@ async function main() {
1747
1747
  // Reserve the port by binding a socket to it
1748
1748
  try {
1749
1749
  await portReserver.reserve(port);
1750
- console.error(`[cdp-tools] Reserved debug port: ${port}`);
1750
+ console.error(`[devharness] Reserved debug port: ${port}`);
1751
1751
  reservationSucceeded = true;
1752
1752
  }
1753
1753
  catch (error) {
1754
1754
  attempts++;
1755
- console.error(`[cdp-tools] Port ${port} reservation failed (attempt ${attempts}/${maxAttempts}), trying next port...`);
1755
+ console.error(`[devharness] Port ${port} reservation failed (attempt ${attempts}/${maxAttempts}), trying next port...`);
1756
1756
  if (attempts >= maxAttempts) {
1757
- console.error(`[cdp-tools] Failed to reserve a port after ${maxAttempts} attempts`);
1757
+ console.error(`[devharness] Failed to reserve a port after ${maxAttempts} attempts`);
1758
1758
  process.exit(1);
1759
1759
  }
1760
1760
  // Try the next port
@@ -1771,12 +1771,12 @@ async function main() {
1771
1771
  registerToolHandlers(server);
1772
1772
  const toolRegistrationTime = performance.now() - toolRegistrationStart;
1773
1773
  // Connect to transport
1774
- console.error(`[cdp-tools] Connecting to transport (PID: ${process.pid})`);
1774
+ console.error(`[devharness] Connecting to transport (PID: ${process.pid})`);
1775
1775
  const transportStart = performance.now();
1776
1776
  const transport = new StdioServerTransport();
1777
1777
  await server.connect(transport);
1778
1778
  const transportTime = performance.now() - transportStart;
1779
- console.error(`[cdp-tools] Transport connected (PID: ${process.pid})`);
1779
+ console.error(`[devharness] Transport connected (PID: ${process.pid})`);
1780
1780
  // Note: Config was already loaded earlier (before orchestrator startup) for debug logging
1781
1781
  // Announce this session BEFORE the manager decides anything: collection asks
1782
1782
  // whether another live session is working in a server's directory, and a
@@ -1786,16 +1786,16 @@ async function main() {
1786
1786
  // Initialize server manager - recover running servers and start auto-run servers
1787
1787
  const serverInitResult = await serverManager.initialize();
1788
1788
  if (serverInitResult.recovered.length > 0) {
1789
- console.error(`[cdp-tools] Recovered ${serverInitResult.recovered.length} running server(s): ${serverInitResult.recovered.join(', ')}`);
1789
+ console.error(`[devharness] Recovered ${serverInitResult.recovered.length} running server(s): ${serverInitResult.recovered.join(', ')}`);
1790
1790
  }
1791
1791
  if (serverInitResult.started.length > 0) {
1792
- console.error(`[cdp-tools] Auto-started ${serverInitResult.started.length} server(s): ${serverInitResult.started.join(', ')}`);
1792
+ console.error(`[devharness] Auto-started ${serverInitResult.started.length} server(s): ${serverInitResult.started.join(', ')}`);
1793
1793
  }
1794
1794
  if (serverInitResult.failed.length > 0) {
1795
- console.error(`[cdp-tools] Failed to auto-start ${serverInitResult.failed.length} server(s): ${serverInitResult.failed.join(', ')}`);
1795
+ console.error(`[devharness] Failed to auto-start ${serverInitResult.failed.length} server(s): ${serverInitResult.failed.join(', ')}`);
1796
1796
  }
1797
1797
  // Dashboard is initialized in session detection callback after sessionId is known
1798
- console.error(`[cdp-tools] Server ready (PID: ${process.pid})`);
1798
+ console.error(`[devharness] Server ready (PID: ${process.pid})`);
1799
1799
  // Calculate total startup time and store metrics for later logging
1800
1800
  const totalStartupTime = performance.now() - STARTUP_TIME;
1801
1801
  setStartupMetrics({
@@ -1829,12 +1829,12 @@ async function main() {
1829
1829
  // autoConnect: false and never connected, or orphaned by some other cleanup path).
1830
1830
  const closedCount = await connectionManager.closeInactiveConnections(INACTIVITY_THRESHOLD);
1831
1831
  if (closedCount > 0) {
1832
- console.error(`[cdp-tools] Closed ${closedCount} inactive connection(s)`);
1832
+ console.error(`[devharness] Closed ${closedCount} inactive connection(s)`);
1833
1833
  await debugLog('index', `Closed ${closedCount} inactive connection(s)`);
1834
1834
  }
1835
1835
  for (const port of chromeLauncher.getRunningPorts()) {
1836
1836
  if (!connectionManager.hasBrowser('localhost', port)) {
1837
- console.error(`[cdp-tools] Killing orphaned Chrome on port ${port} (no tracked connections)`);
1837
+ console.error(`[devharness] Killing orphaned Chrome on port ${port} (no tracked connections)`);
1838
1838
  await debugLog('index', `Killing orphaned Chrome on port ${port} (no tracked connections) due to inactivity`);
1839
1839
  chromeLauncher.setPendingCloseReason(port, 'inactivity');
1840
1840
  await chromeLauncher.kill(port);
@@ -1842,7 +1842,7 @@ async function main() {
1842
1842
  }
1843
1843
  }
1844
1844
  catch (error) {
1845
- console.error(`[cdp-tools] Error during cleanup: ${error}`);
1845
+ console.error(`[devharness] Error during cleanup: ${error}`);
1846
1846
  await debugLog('index', `Error during inactivity cleanup: ${error}`);
1847
1847
  }
1848
1848
  }, CLEANUP_INTERVAL) : null;
@@ -1864,7 +1864,7 @@ async function main() {
1864
1864
  return; // Prevent multiple cleanup calls
1865
1865
  }
1866
1866
  isCleaningUp = true;
1867
- console.error(`[cdp-tools] Received ${signal}, cleaning up...`);
1867
+ console.error(`[devharness] Received ${signal}, cleaning up...`);
1868
1868
  try {
1869
1869
  if (cleanupInterval)
1870
1870
  clearInterval(cleanupInterval); // Stop periodic cleanup
@@ -1876,15 +1876,15 @@ async function main() {
1876
1876
  try {
1877
1877
  const { stopped, keptForOthers } = await serverManager.stopOwnedServers();
1878
1878
  if (stopped.length > 0) {
1879
- console.error(`[cdp-tools] Stopped ${stopped.length} owned dev server(s): ${stopped.join(', ')}`);
1879
+ console.error(`[devharness] Stopped ${stopped.length} owned dev server(s): ${stopped.join(', ')}`);
1880
1880
  }
1881
1881
  if (keptForOthers.length > 0) {
1882
- console.error(`[cdp-tools] Left ${keptForOthers.length} dev server(s) for other sessions: ${keptForOthers.join(', ')}`);
1882
+ console.error(`[devharness] Left ${keptForOthers.length} dev server(s) for other sessions: ${keptForOthers.join(', ')}`);
1883
1883
  }
1884
1884
  await serverManager.getPortMonitor().stopAll();
1885
1885
  }
1886
1886
  catch (error) {
1887
- console.error(`[cdp-tools] Error releasing dev servers: ${error}`);
1887
+ console.error(`[devharness] Error releasing dev servers: ${error}`);
1888
1888
  }
1889
1889
  // This session is over: nothing of ours may keep pinning a server that
1890
1890
  // the next session would otherwise collect.
@@ -1920,12 +1920,12 @@ async function main() {
1920
1920
  : { cleaned: [] };
1921
1921
  const totalCleaned = globalCleaned.cleaned.length + localCleaned.cleaned.length;
1922
1922
  if (totalCleaned > 0) {
1923
- console.error(`[cdp-tools] Cleaned ${totalCleaned} temp file(s) on shutdown`);
1923
+ console.error(`[devharness] Cleaned ${totalCleaned} temp file(s) on shutdown`);
1924
1924
  }
1925
- console.error('[cdp-tools] Cleanup complete');
1925
+ console.error('[devharness] Cleanup complete');
1926
1926
  }
1927
1927
  catch (error) {
1928
- console.error(`[cdp-tools] Cleanup error: ${error}`);
1928
+ console.error(`[devharness] Cleanup error: ${error}`);
1929
1929
  }
1930
1930
  process.exit(0);
1931
1931
  };
@@ -1947,7 +1947,7 @@ async function main() {
1947
1947
  // Handle normal exit (catch-all)
1948
1948
  process.on('exit', () => {
1949
1949
  if (!isCleaningUp) {
1950
- console.error('[cdp-tools] Process exiting');
1950
+ console.error('[devharness] Process exiting');
1951
1951
  }
1952
1952
  });
1953
1953
  // Catch uncaught exceptions and unhandled rejections for debugging.
@@ -1973,7 +1973,7 @@ async function main() {
1973
1973
  const msg = (error && error.message) ? error.message : String(error);
1974
1974
  if (msg === lastUncaughtMsg && now - lastUncaughtAt < 1000) {
1975
1975
  if (++uncaughtCount > 50) {
1976
- writeErr('[cdp-tools] Same uncaught exception >50x in <1s — exiting to break the loop.');
1976
+ writeErr('[devharness] Same uncaught exception >50x in <1s — exiting to break the loop.');
1977
1977
  process.exit(1);
1978
1978
  }
1979
1979
  return;
@@ -1981,21 +1981,21 @@ async function main() {
1981
1981
  lastUncaughtMsg = msg;
1982
1982
  lastUncaughtAt = now;
1983
1983
  uncaughtCount = 0;
1984
- writeErr(`[cdp-tools] UNCAUGHT EXCEPTION (${origin}): ${msg}`);
1984
+ writeErr(`[devharness] UNCAUGHT EXCEPTION (${origin}): ${msg}`);
1985
1985
  try {
1986
1986
  const s = error?.stack;
1987
1987
  if (s)
1988
- writeErr(`[cdp-tools] Stack: ${s}`);
1988
+ writeErr(`[devharness] Stack: ${s}`);
1989
1989
  }
1990
1990
  catch { /* stack getter can throw */ }
1991
1991
  });
1992
1992
  process.on('unhandledRejection', (reason) => {
1993
1993
  const msg = (reason && reason.message) ? reason.message : String(reason);
1994
- writeErr(`[cdp-tools] UNHANDLED REJECTION: ${msg}`);
1994
+ writeErr(`[devharness] UNHANDLED REJECTION: ${msg}`);
1995
1995
  try {
1996
1996
  const s = reason?.stack;
1997
1997
  if (s)
1998
- writeErr(`[cdp-tools] Stack: ${s}`);
1998
+ writeErr(`[devharness] Stack: ${s}`);
1999
1999
  }
2000
2000
  catch { /* stack getter can throw */ }
2001
2001
  });