devharness 0.9.7 → 0.9.9

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 (119) hide show
  1. package/README.md +15 -0
  2. package/build/block-events.d.ts +3 -5
  3. package/build/block-events.d.ts.map +1 -1
  4. package/build/block-events.js +6 -24
  5. package/build/block-events.js.map +1 -1
  6. package/build/block-events.test.js +10 -7
  7. package/build/block-events.test.js.map +1 -1
  8. package/build/cdp-manager.d.ts +7 -0
  9. package/build/cdp-manager.d.ts.map +1 -1
  10. package/build/cdp-manager.js +9 -0
  11. package/build/cdp-manager.js.map +1 -1
  12. package/build/cli/index.d.ts +26 -0
  13. package/build/cli/index.d.ts.map +1 -0
  14. package/build/cli/index.js +290 -0
  15. package/build/cli/index.js.map +1 -0
  16. package/build/cli/process-tree.d.ts +21 -0
  17. package/build/cli/process-tree.d.ts.map +1 -0
  18. package/build/cli/process-tree.js +51 -0
  19. package/build/cli/process-tree.js.map +1 -0
  20. package/build/cli/session-match.d.ts +37 -0
  21. package/build/cli/session-match.d.ts.map +1 -0
  22. package/build/cli/session-match.js +55 -0
  23. package/build/cli/session-match.js.map +1 -0
  24. package/build/cli/session-match.test.d.ts +17 -0
  25. package/build/cli/session-match.test.d.ts.map +1 -0
  26. package/build/cli/session-match.test.js +125 -0
  27. package/build/cli/session-match.test.js.map +1 -0
  28. package/build/config.d.ts +1 -1
  29. package/build/config.d.ts.map +1 -1
  30. package/build/config.js +1 -0
  31. package/build/config.js.map +1 -1
  32. package/build/connection-manager.d.ts.map +1 -1
  33. package/build/connection-manager.js +6 -1
  34. package/build/connection-manager.js.map +1 -1
  35. package/build/index.js +57 -4
  36. package/build/index.js.map +1 -1
  37. package/build/mcp-supervisor.js +43 -0
  38. package/build/mcp-supervisor.js.map +1 -1
  39. package/build/network-monitor.d.ts +13 -2
  40. package/build/network-monitor.d.ts.map +1 -1
  41. package/build/network-monitor.js +54 -23
  42. package/build/network-monitor.js.map +1 -1
  43. package/build/network-monitor.test.d.ts +11 -0
  44. package/build/network-monitor.test.d.ts.map +1 -0
  45. package/build/network-monitor.test.js +151 -0
  46. package/build/network-monitor.test.js.map +1 -0
  47. package/build/plugin-session-start-hook.test.d.ts +10 -0
  48. package/build/plugin-session-start-hook.test.d.ts.map +1 -0
  49. package/build/plugin-session-start-hook.test.js +187 -0
  50. package/build/plugin-session-start-hook.test.js.map +1 -0
  51. package/build/session-endpoint.d.ts +72 -0
  52. package/build/session-endpoint.d.ts.map +1 -0
  53. package/build/session-endpoint.js +220 -0
  54. package/build/session-endpoint.js.map +1 -0
  55. package/build/session-endpoint.test.d.ts +10 -0
  56. package/build/session-endpoint.test.d.ts.map +1 -0
  57. package/build/session-endpoint.test.js +202 -0
  58. package/build/session-endpoint.test.js.map +1 -0
  59. package/build/session-events.d.ts +28 -0
  60. package/build/session-events.d.ts.map +1 -0
  61. package/build/session-events.js +38 -0
  62. package/build/session-events.js.map +1 -0
  63. package/build/session-events.test.d.ts +8 -0
  64. package/build/session-events.test.d.ts.map +1 -0
  65. package/build/session-events.test.js +56 -0
  66. package/build/session-events.test.js.map +1 -0
  67. package/build/session-identity.d.ts +56 -0
  68. package/build/session-identity.d.ts.map +1 -0
  69. package/build/session-identity.js +96 -0
  70. package/build/session-identity.js.map +1 -0
  71. package/build/session-identity.test.d.ts +9 -0
  72. package/build/session-identity.test.d.ts.map +1 -0
  73. package/build/session-identity.test.js +126 -0
  74. package/build/session-identity.test.js.map +1 -0
  75. package/build/session-messages.d.ts +70 -0
  76. package/build/session-messages.d.ts.map +1 -0
  77. package/build/session-messages.js +139 -0
  78. package/build/session-messages.js.map +1 -0
  79. package/build/tool-response.d.ts +40 -1
  80. package/build/tool-response.d.ts.map +1 -1
  81. package/build/tool-response.js.map +1 -1
  82. package/build/tools/console-tools.d.ts +4 -0
  83. package/build/tools/console-tools.d.ts.map +1 -1
  84. package/build/tools/console-tools.js +55 -1
  85. package/build/tools/console-tools.js.map +1 -1
  86. package/build/tools/inspect-worker-meta.test.d.ts +9 -0
  87. package/build/tools/inspect-worker-meta.test.d.ts.map +1 -0
  88. package/build/tools/inspect-worker-meta.test.js +122 -0
  89. package/build/tools/inspect-worker-meta.test.js.map +1 -0
  90. package/build/tools/inspection-tools.d.ts +12 -5
  91. package/build/tools/inspection-tools.d.ts.map +1 -1
  92. package/build/tools/inspection-tools.js +86 -5
  93. package/build/tools/inspection-tools.js.map +1 -1
  94. package/build/tools/issues-tools.d.ts +3 -3
  95. package/build/tools/message-tools.d.ts +51 -0
  96. package/build/tools/message-tools.d.ts.map +1 -0
  97. package/build/tools/message-tools.js +250 -0
  98. package/build/tools/message-tools.js.map +1 -0
  99. package/build/tools/message-tools.test.d.ts +9 -0
  100. package/build/tools/message-tools.test.d.ts.map +1 -0
  101. package/build/tools/message-tools.test.js +332 -0
  102. package/build/tools/message-tools.test.js.map +1 -0
  103. package/build/tools/network-tools.js +1 -1
  104. package/build/tools/network-tools.js.map +1 -1
  105. package/build/tools/replay-tools.d.ts +3 -3
  106. package/build/tools/server-tools.d.ts +3 -3
  107. package/build/worker-targets.d.ts +75 -0
  108. package/build/worker-targets.d.ts.map +1 -0
  109. package/build/worker-targets.js +171 -0
  110. package/build/worker-targets.js.map +1 -0
  111. package/build/worker-targets.test.d.ts +8 -0
  112. package/build/worker-targets.test.d.ts.map +1 -0
  113. package/build/worker-targets.test.js +118 -0
  114. package/build/worker-targets.test.js.map +1 -0
  115. package/docs/instructions.md +23 -12
  116. package/docs/messages.md +150 -0
  117. package/package.json +3 -1
  118. package/plugin/skills/devharness/SKILL.md +36 -8
  119. package/plugin/skills/devharness/references/tool-categories.md +8 -1
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Which Claude Code session this process serves.
3
+ *
4
+ * Claude Code exports CLAUDE_CODE_SESSION_ID into the environment it spawns
5
+ * the supervisor with, and the child inherits it. That value is present from
6
+ * the first instruction and unchanged when the supervisor replaces the child,
7
+ * so anything naming this session on disk - a mailbox filename, a presence
8
+ * record - keeps the same name across a rebuild.
9
+ *
10
+ * The session detector produces the same id, but only after a tool response
11
+ * carrying a `pid:` footer has been written into the session's .jsonl and
12
+ * matched. A session driven from the CLI writes no such footer, and a child
13
+ * restarted by a rebuild has not written one yet.
14
+ */
15
+ /** The full session id from the environment, or undefined when this process
16
+ * was not spawned by Claude Code. */
17
+ export declare function getClaudeSessionId(): string | undefined;
18
+ /** The first 8 characters of the session id - the form the dashboard and the
19
+ * session detector both display. */
20
+ export declare function getClaudeShortId(): string | undefined;
21
+ /**
22
+ * The name this session is known by on disk - its mailbox filename, its event
23
+ * stream filename, its presence record.
24
+ *
25
+ * The hook's record comes first: it is the only source that follows the
26
+ * conversation through a `/clear`, which changes the id without restarting this
27
+ * process. The environment is next, correct from the first instruction and for
28
+ * as long as the conversation lasts. The detector covers a client that exports
29
+ * no session id. The pid form is last, and changes on every restart, which is
30
+ * why it is the fallback rather than the default.
31
+ */
32
+ export declare function resolveSessionName(detectedShortId?: string): string;
33
+ /**
34
+ * The Claude process this server belongs to.
35
+ *
36
+ * `CLAUDE_CODE_MESSAGING_SOCKET` carries that pid in its filename, and it is
37
+ * present in both the hook's environment and the server's, under `-p` and
38
+ * interactively. `CLAUDE_PID` carries it more directly and is absent from the
39
+ * server under `-p`, so the socket path is the derivation that works on both
40
+ * sides.
41
+ */
42
+ export declare function getClientPid(): number | undefined;
43
+ /** Where the plugin's SessionStart hook records the conversation a client is
44
+ * currently on. */
45
+ export declare function getClientsDir(): string;
46
+ export declare function getClientRecordPath(clientPid: number): string;
47
+ /**
48
+ * The conversation this client is on now, as last written by the hook.
49
+ *
50
+ * `CLAUDE_CODE_SESSION_ID` is read once when the process is spawned, and
51
+ * `/clear` gives the conversation a new id without restarting it. The hook runs
52
+ * on every start reason including `clear`, carrying the current id, so this
53
+ * file is the only source that tracks the change while the process lives.
54
+ */
55
+ export declare function readCurrentSessionId(): string | undefined;
56
+ //# sourceMappingURL=session-identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-identity.d.ts","sourceRoot":"","sources":["../src/session-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAUH;sCACsC;AACtC,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,SAAS,CAIvD;AAED;qCACqC;AACrC,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,SAAS,CAErD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAKnE;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,IAAI,MAAM,GAAG,SAAS,CAKjD;AAED;oBACoB;AACpB,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,GAAG,SAAS,CAUzD"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Which Claude Code session this process serves.
3
+ *
4
+ * Claude Code exports CLAUDE_CODE_SESSION_ID into the environment it spawns
5
+ * the supervisor with, and the child inherits it. That value is present from
6
+ * the first instruction and unchanged when the supervisor replaces the child,
7
+ * so anything naming this session on disk - a mailbox filename, a presence
8
+ * record - keeps the same name across a rebuild.
9
+ *
10
+ * The session detector produces the same id, but only after a tool response
11
+ * carrying a `pid:` footer has been written into the session's .jsonl and
12
+ * matched. A session driven from the CLI writes no such footer, and a child
13
+ * restarted by a rebuild has not written one yet.
14
+ */
15
+ import { readFileSync } from 'fs';
16
+ import { join, basename } from 'path';
17
+ import { getOutputPath } from './helpers/paths.js';
18
+ /** Ids become filenames; anything outside this set could escape the directory
19
+ * holding them. */
20
+ const SESSION_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
21
+ /** The full session id from the environment, or undefined when this process
22
+ * was not spawned by Claude Code. */
23
+ export function getClaudeSessionId() {
24
+ const value = process.env.CLAUDE_CODE_SESSION_ID;
25
+ if (!value || !SESSION_ID_PATTERN.test(value))
26
+ return undefined;
27
+ return value;
28
+ }
29
+ /** The first 8 characters of the session id - the form the dashboard and the
30
+ * session detector both display. */
31
+ export function getClaudeShortId() {
32
+ return getClaudeSessionId()?.slice(0, 8);
33
+ }
34
+ /**
35
+ * The name this session is known by on disk - its mailbox filename, its event
36
+ * stream filename, its presence record.
37
+ *
38
+ * The hook's record comes first: it is the only source that follows the
39
+ * conversation through a `/clear`, which changes the id without restarting this
40
+ * process. The environment is next, correct from the first instruction and for
41
+ * as long as the conversation lasts. The detector covers a client that exports
42
+ * no session id. The pid form is last, and changes on every restart, which is
43
+ * why it is the fallback rather than the default.
44
+ */
45
+ export function resolveSessionName(detectedShortId) {
46
+ return readCurrentSessionId()?.slice(0, 8)
47
+ ?? getClaudeShortId()
48
+ ?? detectedShortId
49
+ ?? `pid-${process.pid}`;
50
+ }
51
+ /**
52
+ * The Claude process this server belongs to.
53
+ *
54
+ * `CLAUDE_CODE_MESSAGING_SOCKET` carries that pid in its filename, and it is
55
+ * present in both the hook's environment and the server's, under `-p` and
56
+ * interactively. `CLAUDE_PID` carries it more directly and is absent from the
57
+ * server under `-p`, so the socket path is the derivation that works on both
58
+ * sides.
59
+ */
60
+ export function getClientPid() {
61
+ const socket = process.env.CLAUDE_CODE_MESSAGING_SOCKET;
62
+ if (!socket)
63
+ return undefined;
64
+ const pid = Number(basename(socket).replace(/\.sock$/, ''));
65
+ return Number.isInteger(pid) && pid > 0 ? pid : undefined;
66
+ }
67
+ /** Where the plugin's SessionStart hook records the conversation a client is
68
+ * currently on. */
69
+ export function getClientsDir() {
70
+ return getOutputPath('clients', { global: true });
71
+ }
72
+ export function getClientRecordPath(clientPid) {
73
+ return join(getClientsDir(), `${clientPid}.json`);
74
+ }
75
+ /**
76
+ * The conversation this client is on now, as last written by the hook.
77
+ *
78
+ * `CLAUDE_CODE_SESSION_ID` is read once when the process is spawned, and
79
+ * `/clear` gives the conversation a new id without restarting it. The hook runs
80
+ * on every start reason including `clear`, carrying the current id, so this
81
+ * file is the only source that tracks the change while the process lives.
82
+ */
83
+ export function readCurrentSessionId() {
84
+ const clientPid = getClientPid();
85
+ if (clientPid === undefined)
86
+ return undefined;
87
+ try {
88
+ const record = JSON.parse(readFileSync(getClientRecordPath(clientPid), 'utf-8'));
89
+ const id = record?.sessionId;
90
+ return typeof id === 'string' && SESSION_ID_PATTERN.test(id) ? id : undefined;
91
+ }
92
+ catch {
93
+ return undefined;
94
+ }
95
+ }
96
+ //# sourceMappingURL=session-identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-identity.js","sourceRoot":"","sources":["../src/session-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD;oBACoB;AACpB,MAAM,kBAAkB,GAAG,oCAAoC,CAAC;AAEhE;sCACsC;AACtC,MAAM,UAAU,kBAAkB;IAChC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC;IACjD,IAAI,CAAC,KAAK,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAChE,OAAO,KAAK,CAAC;AACf,CAAC;AAED;qCACqC;AACrC,MAAM,UAAU,gBAAgB;IAC9B,OAAO,kBAAkB,EAAE,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,kBAAkB,CAAC,eAAwB;IACzD,OAAO,oBAAoB,EAAE,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;WACrC,gBAAgB,EAAE;WAClB,eAAe;WACf,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC;AAC5B,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC;IACxD,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC9B,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC;IAC5D,OAAO,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;AAC5D,CAAC;AAED;oBACoB;AACpB,MAAM,UAAU,aAAa;IAC3B,OAAO,aAAa,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,SAAiB;IACnD,OAAO,IAAI,CAAC,aAAa,EAAE,EAAE,GAAG,SAAS,OAAO,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB;IAClC,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;IACjC,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC9C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,mBAAmB,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;QACjF,MAAM,EAAE,GAAG,MAAM,EAAE,SAAS,CAAC;QAC7B,OAAO,OAAO,EAAE,KAAK,QAAQ,IAAI,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAChF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Tests for reading the Claude Code session id out of the environment.
3
+ *
4
+ * The id becomes a filename, so a value that could traverse out of the
5
+ * directory holding mailboxes and presence records is rejected rather than
6
+ * sanitised - a sanitised name would silently address a different session.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=session-identity.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-identity.test.d.ts","sourceRoot":"","sources":["../src/session-identity.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Tests for reading the Claude Code session id out of the environment.
3
+ *
4
+ * The id becomes a filename, so a value that could traverse out of the
5
+ * directory holding mailboxes and presence records is rejected rather than
6
+ * sanitised - a sanitised name would silently address a different session.
7
+ */
8
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
9
+ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from 'fs';
10
+ import { tmpdir } from 'os';
11
+ import { join } from 'path';
12
+ import { initializePaths } from './helpers/paths.js';
13
+ import { getClaudeSessionId, getClaudeShortId, getClientPid, readCurrentSessionId, resolveSessionName, getClientRecordPath, } from './session-identity.js';
14
+ let previous;
15
+ let previousSocket;
16
+ let previousDir;
17
+ let dir;
18
+ beforeEach(() => {
19
+ previous = process.env.CLAUDE_CODE_SESSION_ID;
20
+ previousSocket = process.env.CLAUDE_CODE_MESSAGING_SOCKET;
21
+ previousDir = process.env.DEVHARNESS_DIR;
22
+ dir = mkdtempSync(join(tmpdir(), 'devharness-identity-'));
23
+ process.env.DEVHARNESS_DIR = dir;
24
+ initializePaths();
25
+ });
26
+ afterEach(() => {
27
+ if (previous === undefined)
28
+ delete process.env.CLAUDE_CODE_SESSION_ID;
29
+ else
30
+ process.env.CLAUDE_CODE_SESSION_ID = previous;
31
+ if (previousSocket === undefined)
32
+ delete process.env.CLAUDE_CODE_MESSAGING_SOCKET;
33
+ else
34
+ process.env.CLAUDE_CODE_MESSAGING_SOCKET = previousSocket;
35
+ if (previousDir === undefined)
36
+ delete process.env.DEVHARNESS_DIR;
37
+ else
38
+ process.env.DEVHARNESS_DIR = previousDir;
39
+ initializePaths();
40
+ rmSync(dir, { recursive: true, force: true });
41
+ });
42
+ /** What the hook writes when a conversation starts or is cleared. */
43
+ function hookRecorded(clientPid, sessionId) {
44
+ const path = getClientRecordPath(clientPid);
45
+ mkdirSync(join(dir, 'clients'), { recursive: true });
46
+ writeFileSync(path, JSON.stringify({ sessionId, at: '2026-08-21T00:00:00.000Z' }));
47
+ }
48
+ describe('getClaudeSessionId', () => {
49
+ it('returns the exported id', () => {
50
+ process.env.CLAUDE_CODE_SESSION_ID = '2e9119bf-672e-4ad8-89c1-f44fcd1060d8';
51
+ expect(getClaudeSessionId()).toBe('2e9119bf-672e-4ad8-89c1-f44fcd1060d8');
52
+ });
53
+ it('returns undefined when the process was not spawned by Claude Code', () => {
54
+ delete process.env.CLAUDE_CODE_SESSION_ID;
55
+ expect(getClaudeSessionId()).toBeUndefined();
56
+ expect(getClaudeShortId()).toBeUndefined();
57
+ });
58
+ it('returns undefined for an empty value', () => {
59
+ process.env.CLAUDE_CODE_SESSION_ID = '';
60
+ expect(getClaudeSessionId()).toBeUndefined();
61
+ });
62
+ it('rejects a value that would write outside the directory naming it', () => {
63
+ for (const bad of ['../escape', 'a/b', '..', '.hidden', 'has space', 'x'.repeat(200)]) {
64
+ process.env.CLAUDE_CODE_SESSION_ID = bad;
65
+ expect(getClaudeSessionId()).toBeUndefined();
66
+ }
67
+ });
68
+ });
69
+ describe('getClaudeShortId', () => {
70
+ it('is the first eight characters, the form the dashboard shows', () => {
71
+ process.env.CLAUDE_CODE_SESSION_ID = '2e9119bf-672e-4ad8-89c1-f44fcd1060d8';
72
+ expect(getClaudeShortId()).toBe('2e9119bf');
73
+ });
74
+ it('returns a short id shorter than eight characters unchanged', () => {
75
+ process.env.CLAUDE_CODE_SESSION_ID = 'abc';
76
+ expect(getClaudeShortId()).toBe('abc');
77
+ });
78
+ });
79
+ describe('getClientPid', () => {
80
+ it('reads the Claude pid out of the messaging socket path', () => {
81
+ process.env.CLAUDE_CODE_MESSAGING_SOCKET = '/tmp/cc-socks/61220.sock';
82
+ expect(getClientPid()).toBe(61220);
83
+ });
84
+ it('returns undefined when no socket is exported', () => {
85
+ delete process.env.CLAUDE_CODE_MESSAGING_SOCKET;
86
+ expect(getClientPid()).toBeUndefined();
87
+ });
88
+ it('returns undefined for a socket path that names no pid', () => {
89
+ process.env.CLAUDE_CODE_MESSAGING_SOCKET = '/tmp/cc-socks/not-a-pid.sock';
90
+ expect(getClientPid()).toBeUndefined();
91
+ });
92
+ });
93
+ describe('resolveSessionName - following a conversation through a clear', () => {
94
+ beforeEach(() => {
95
+ process.env.CLAUDE_CODE_MESSAGING_SOCKET = '/tmp/cc-socks/61220.sock';
96
+ // The value this process was spawned with, which /clear does not update.
97
+ process.env.CLAUDE_CODE_SESSION_ID = 'aaaaaaaa-1111-2222-3333-444444444444';
98
+ });
99
+ it('uses the environment while the hook has recorded the same conversation', () => {
100
+ hookRecorded(61220, 'aaaaaaaa-1111-2222-3333-444444444444');
101
+ expect(resolveSessionName()).toBe('aaaaaaaa');
102
+ });
103
+ it('follows the hook to the new conversation after a clear', () => {
104
+ hookRecorded(61220, 'bbbbbbbb-9999-0000-1111-222222222222');
105
+ expect(readCurrentSessionId()).toBe('bbbbbbbb-9999-0000-1111-222222222222');
106
+ expect(resolveSessionName()).toBe('bbbbbbbb');
107
+ });
108
+ it('falls back to the environment when no hook has run', () => {
109
+ expect(readCurrentSessionId()).toBeUndefined();
110
+ expect(resolveSessionName()).toBe('aaaaaaaa');
111
+ });
112
+ it('falls back to the environment when the record names a different client', () => {
113
+ hookRecorded(99999, 'bbbbbbbb-9999');
114
+ expect(resolveSessionName()).toBe('aaaaaaaa');
115
+ });
116
+ it('ignores a recorded id that would escape the directory naming it', () => {
117
+ hookRecorded(61220, '../../escape');
118
+ expect(readCurrentSessionId()).toBeUndefined();
119
+ expect(resolveSessionName()).toBe('aaaaaaaa');
120
+ });
121
+ it('falls back to the detector when neither the record nor the environment has one', () => {
122
+ delete process.env.CLAUDE_CODE_SESSION_ID;
123
+ expect(resolveSessionName('cccccccc')).toBe('cccccccc');
124
+ });
125
+ });
126
+ //# sourceMappingURL=session-identity.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-identity.test.js","sourceRoot":"","sources":["../src/session-identity.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Cross-session messages: the mailbox one devharness session appends to and
3
+ * another one reads.
4
+ *
5
+ * Each session owns `~/.devharness/messages/<id>.jsonl`, one JSON object per
6
+ * line. The global directory is required rather than preferred: a supervisor
7
+ * is scoped to a project root, so two sessions in different roots share no
8
+ * process, and only the home directory is reachable from both.
9
+ *
10
+ * The mailbox holds the conversation and the read cursor. An arrival is
11
+ * announced separately on the session's event stream, which is the one file a
12
+ * Monitor tails, so no watch is armed on a mailbox.
13
+ */
14
+ export interface SessionMessage {
15
+ /** Identity a reply carries in `replyTo`. */
16
+ id: string;
17
+ /** Mailbox id of the sender. */
18
+ from: string;
19
+ /** Project directory of the sender, so a listing names the repo. */
20
+ fromCwd?: string;
21
+ /** Mailbox id this line was appended to. */
22
+ to: string;
23
+ text: string;
24
+ /** On a reply, the id of the message it answers. */
25
+ replyTo?: string;
26
+ /** ISO timestamp of the append. */
27
+ at: string;
28
+ }
29
+ export interface MailboxCursor {
30
+ /** Lines already returned by `read`. The file is append-only, so a line
31
+ * count is a stable cursor across processes. */
32
+ readLines: number;
33
+ }
34
+ export declare function isValidMailboxId(id: string): boolean;
35
+ export declare function getMessagesDir(): string;
36
+ export declare function getMailboxPath(id: string): string;
37
+ /** Every message in a mailbox, oldest first. A line that does not parse is
38
+ * skipped: one torn write must not hide every message after it. */
39
+ export declare function readMailbox(id: string): Promise<SessionMessage[]>;
40
+ /** Mailbox ids that have a file on disk. Covers sessions that have exited,
41
+ * which is what makes a reply to a dead session visible rather than silent. */
42
+ export declare function listMailboxIds(): Promise<string[]>;
43
+ export interface SendMessageInput {
44
+ from: string;
45
+ fromCwd?: string;
46
+ to: string;
47
+ text: string;
48
+ replyTo?: string;
49
+ }
50
+ /** Append one message to the recipient's mailbox and return the line written. */
51
+ export declare function sendMessage(input: SendMessageInput): Promise<SessionMessage>;
52
+ export declare function readCursor(id: string): Promise<number>;
53
+ export declare function writeCursor(id: string, readLines: number): Promise<void>;
54
+ export interface WaitForMailboxOptions {
55
+ timeoutMs: number;
56
+ pollIntervalMs: number;
57
+ abortSignal?: AbortSignal;
58
+ }
59
+ /**
60
+ * Poll `id`'s mailbox until it holds more than `fromLine` messages, and return
61
+ * the ones past that point. An empty array means the timeout elapsed with
62
+ * nothing new.
63
+ *
64
+ * The return fires on ANY new message, not only one whose `replyTo` matches.
65
+ * Two sessions that block at the same moment are both inside this loop and
66
+ * neither is reading its mailbox; returning on any arrival releases both,
67
+ * where a reply-tagged match would hold each until its own timeout.
68
+ */
69
+ export declare function waitForMailbox(id: string, fromLine: number, options: WaitForMailboxOptions): Promise<SessionMessage[]>;
70
+ //# sourceMappingURL=session-messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-messages.d.ts","sourceRoot":"","sources":["../src/session-messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH,MAAM,WAAW,cAAc;IAC7B,6CAA6C;IAC7C,EAAE,EAAE,MAAM,CAAC;IACX,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mCAAmC;IACnC,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,aAAa;IAC5B;qDACiD;IACjD,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAEjD;AAiBD;oEACoE;AACpE,wBAAsB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAYvE;AAED;gFACgF;AAChF,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAWxD;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,iFAAiF;AACjF,wBAAsB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,CAAC,CAclF;AAED,wBAAsB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAS5D;AAED,wBAAsB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI9E;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAClC,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,cAAc,EAAE,CAAC,CAoB3B"}
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Cross-session messages: the mailbox one devharness session appends to and
3
+ * another one reads.
4
+ *
5
+ * Each session owns `~/.devharness/messages/<id>.jsonl`, one JSON object per
6
+ * line. The global directory is required rather than preferred: a supervisor
7
+ * is scoped to a project root, so two sessions in different roots share no
8
+ * process, and only the home directory is reachable from both.
9
+ *
10
+ * The mailbox holds the conversation and the read cursor. An arrival is
11
+ * announced separately on the session's event stream, which is the one file a
12
+ * Monitor tails, so no watch is armed on a mailbox.
13
+ */
14
+ import { promises as fs } from 'fs';
15
+ import { join } from 'path';
16
+ import { randomUUID } from 'crypto';
17
+ import { getOutputPath } from './helpers/paths.js';
18
+ import { abortableSleep, throwIfAborted } from './utils/abort.js';
19
+ /** A mailbox id becomes a filename, so anything outside this set would let a
20
+ * crafted id write outside the messages directory. */
21
+ const MAILBOX_ID_PATTERN = /^[A-Za-z0-9._-]{1,64}$/;
22
+ export function isValidMailboxId(id) {
23
+ return MAILBOX_ID_PATTERN.test(id) && id !== '.' && id !== '..' && !id.includes('..');
24
+ }
25
+ export function getMessagesDir() {
26
+ return getOutputPath('messages', { global: true });
27
+ }
28
+ export function getMailboxPath(id) {
29
+ return join(getMessagesDir(), `${id}.jsonl`);
30
+ }
31
+ function getCursorPath(id) {
32
+ return join(getMessagesDir(), `${id}.cursor.json`);
33
+ }
34
+ /** Read a whole file, or an empty string when it does not exist yet. An
35
+ * absent mailbox is a session that has received nothing, not a failure. */
36
+ async function readFileOrEmpty(path) {
37
+ try {
38
+ return await fs.readFile(path, 'utf-8');
39
+ }
40
+ catch (err) {
41
+ if (err?.code === 'ENOENT')
42
+ return '';
43
+ throw err;
44
+ }
45
+ }
46
+ /** Every message in a mailbox, oldest first. A line that does not parse is
47
+ * skipped: one torn write must not hide every message after it. */
48
+ export async function readMailbox(id) {
49
+ const raw = await readFileOrEmpty(getMailboxPath(id));
50
+ const out = [];
51
+ for (const line of raw.split('\n')) {
52
+ if (!line.trim())
53
+ continue;
54
+ try {
55
+ out.push(JSON.parse(line));
56
+ }
57
+ catch {
58
+ continue;
59
+ }
60
+ }
61
+ return out;
62
+ }
63
+ /** Mailbox ids that have a file on disk. Covers sessions that have exited,
64
+ * which is what makes a reply to a dead session visible rather than silent. */
65
+ export async function listMailboxIds() {
66
+ try {
67
+ const entries = await fs.readdir(getMessagesDir());
68
+ return entries
69
+ .filter(name => name.endsWith('.jsonl'))
70
+ .map(name => name.slice(0, -'.jsonl'.length))
71
+ .sort();
72
+ }
73
+ catch (err) {
74
+ if (err?.code === 'ENOENT')
75
+ return [];
76
+ throw err;
77
+ }
78
+ }
79
+ /** Append one message to the recipient's mailbox and return the line written. */
80
+ export async function sendMessage(input) {
81
+ const message = {
82
+ id: randomUUID(),
83
+ from: input.from,
84
+ ...(input.fromCwd ? { fromCwd: input.fromCwd } : {}),
85
+ to: input.to,
86
+ text: input.text,
87
+ ...(input.replyTo ? { replyTo: input.replyTo } : {}),
88
+ at: new Date().toISOString(),
89
+ };
90
+ await fs.mkdir(getMessagesDir(), { recursive: true });
91
+ await fs.appendFile(getMailboxPath(input.to), JSON.stringify(message) + '\n');
92
+ return message;
93
+ }
94
+ export async function readCursor(id) {
95
+ const raw = await readFileOrEmpty(getCursorPath(id));
96
+ if (!raw.trim())
97
+ return 0;
98
+ try {
99
+ const parsed = JSON.parse(raw);
100
+ return Number.isInteger(parsed.readLines) && parsed.readLines >= 0 ? parsed.readLines : 0;
101
+ }
102
+ catch {
103
+ return 0;
104
+ }
105
+ }
106
+ export async function writeCursor(id, readLines) {
107
+ await fs.mkdir(getMessagesDir(), { recursive: true });
108
+ const cursor = { readLines };
109
+ await fs.writeFile(getCursorPath(id), JSON.stringify(cursor));
110
+ }
111
+ /**
112
+ * Poll `id`'s mailbox until it holds more than `fromLine` messages, and return
113
+ * the ones past that point. An empty array means the timeout elapsed with
114
+ * nothing new.
115
+ *
116
+ * The return fires on ANY new message, not only one whose `replyTo` matches.
117
+ * Two sessions that block at the same moment are both inside this loop and
118
+ * neither is reading its mailbox; returning on any arrival releases both,
119
+ * where a reply-tagged match would hold each until its own timeout.
120
+ */
121
+ export async function waitForMailbox(id, fromLine, options) {
122
+ const start = Date.now();
123
+ while (true) {
124
+ throwIfAborted(options.abortSignal);
125
+ const messages = await readMailbox(id);
126
+ if (messages.length > fromLine) {
127
+ return messages.slice(fromLine);
128
+ }
129
+ // Time remaining, not time remaining after a full interval: the old form
130
+ // returned before sleeping at all whenever the timeout was shorter than one
131
+ // interval, so any wait under the default 500ms never waited.
132
+ const remaining = options.timeoutMs - (Date.now() - start);
133
+ if (remaining <= 0) {
134
+ return [];
135
+ }
136
+ await abortableSleep(Math.min(options.pollIntervalMs, remaining), options.abortSignal);
137
+ }
138
+ }
139
+ //# sourceMappingURL=session-messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-messages.js","sourceRoot":"","sources":["../src/session-messages.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,7 @@
5
5
  import type { PortFailureInfo, PendingStartupFailureInfo, PendingRestartInfo } from './server-manager.js';
6
6
  import type { Connection } from './connection-manager.js';
7
7
  import type { BlockEventInfo } from './block-events.js';
8
+ import type { SessionMessage } from './session-messages.js';
8
9
  /**
9
10
  * Tool response content item
10
11
  */
@@ -115,6 +116,8 @@ export interface InspectToolMeta {
115
116
  valueSource?: 'exact' | 'display';
116
117
  /** Set when the expression was evaluated against a paused call frame */
117
118
  callFrameId?: string;
119
+ /** Set when the expression was evaluated inside a worker target */
120
+ workerTarget?: string;
118
121
  }
119
122
  /**
120
123
  * Storage tool metadata (IndexedDB reads).
@@ -190,10 +193,19 @@ export interface ReplayRunMeta {
190
193
  * This provides structured data for programmatic use (validation, replay)
191
194
  * while keeping text content free to evolve for human/LLM display
192
195
  */
196
+ /** One worker target: service worker, dedicated worker, or shared worker. */
197
+ export interface WorkerTargetMeta {
198
+ targetId: string;
199
+ type: string;
200
+ url: string;
201
+ attached: boolean;
202
+ }
193
203
  export interface ToolResponseMeta {
194
204
  tool: string;
195
205
  action?: string;
196
206
  timestamp: number;
207
+ /** Worker targets on this browser, from inspect({ action: 'listTargets' }). */
208
+ workerTargets?: WorkerTargetMeta[];
197
209
  click?: ClickActionMeta;
198
210
  type?: TypeActionMeta;
199
211
  navigate?: NavigateActionMeta;
@@ -207,6 +219,33 @@ export interface ToolResponseMeta {
207
219
  storage?: StorageToolMeta;
208
220
  replay?: ReplayRunMeta;
209
221
  github?: GithubToolMeta;
222
+ message?: MessageToolMeta;
223
+ }
224
+ /** Structured result of a cross-session message action. Behaviour reads this,
225
+ * never the rendered text. */
226
+ export interface MessageToolMeta {
227
+ action: 'sessions' | 'send' | 'read' | 'reply';
228
+ /** Mailbox id this session is reachable at. */
229
+ self: string;
230
+ /** sessions: every mailbox known, with hub liveness where the hub is up. */
231
+ sessions?: Array<{
232
+ id: string;
233
+ pid?: number;
234
+ cwd?: string;
235
+ live: boolean;
236
+ self: boolean;
237
+ }>;
238
+ /** send/reply: the message appended to the recipient's mailbox. */
239
+ sent?: SessionMessage;
240
+ /** send: whether a session was listening under that id at the time. False
241
+ * for a suspended peer and for a mistyped id alike. */
242
+ targetListening?: boolean;
243
+ /** send/reply/read: messages taken from this session's own mailbox. */
244
+ received?: SessionMessage[];
245
+ /** send/reply with waitForReplyMs: true when the wait returned nothing. */
246
+ waitTimedOut?: boolean;
247
+ /** send/reply with waitForReplyMs: milliseconds spent inside the wait. */
248
+ waitElapsedMs?: number;
210
249
  }
211
250
  /** Structured result of a GitHub action on the issues tool. Behaviour reads
212
251
  * this, never the rendered text. */
@@ -248,7 +287,7 @@ export interface ToolResponse {
248
287
  export interface BlockingResponse {
249
288
  blocked: true;
250
289
  response: ToolResponse;
251
- /** Identity/summary for the blocks.jsonl event stream. */
290
+ /** Identity/summary for the session's event stream. */
252
291
  block?: BlockEventInfo;
253
292
  }
254
293
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"tool-response.d.ts","sourceRoot":"","sources":["../src/tool-response.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tool-response.d.ts","sourceRoot":"","sources":["../src/tool-response.ts"],"names":[],"mappings":"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"}