@indianic/dialout 1.1.2 → 1.2.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 (224) hide show
  1. package/README.md +420 -24
  2. package/bin/AGENTS.md +44 -0
  3. package/bin/devdash-agent.js +2 -0
  4. package/dist/ai-adapters/claude.d.ts +3 -0
  5. package/dist/ai-adapters/claude.d.ts.map +1 -0
  6. package/dist/ai-adapters/claude.js +98 -0
  7. package/dist/ai-adapters/claude.js.map +1 -0
  8. package/dist/ai-adapters/codex.d.ts +3 -0
  9. package/dist/ai-adapters/codex.d.ts.map +1 -0
  10. package/dist/ai-adapters/codex.js +147 -0
  11. package/dist/ai-adapters/codex.js.map +1 -0
  12. package/dist/ai-adapters/grok.d.ts +3 -0
  13. package/dist/ai-adapters/grok.d.ts.map +1 -0
  14. package/dist/ai-adapters/grok.js +164 -0
  15. package/dist/ai-adapters/grok.js.map +1 -0
  16. package/dist/ai-adapters/index.d.ts +5 -0
  17. package/dist/ai-adapters/index.d.ts.map +1 -0
  18. package/dist/ai-adapters/index.js +30 -0
  19. package/dist/ai-adapters/index.js.map +1 -0
  20. package/dist/ai-adapters/types.d.ts +3 -0
  21. package/dist/ai-adapters/types.d.ts.map +1 -0
  22. package/dist/ai-adapters/types.js +7 -0
  23. package/dist/ai-adapters/types.js.map +1 -0
  24. package/dist/ai-capabilities/claude.d.ts +4 -0
  25. package/dist/ai-capabilities/claude.d.ts.map +1 -0
  26. package/dist/ai-capabilities/claude.js +174 -0
  27. package/dist/ai-capabilities/claude.js.map +1 -0
  28. package/dist/ai-capabilities/describe.d.ts +2 -0
  29. package/dist/ai-capabilities/describe.d.ts.map +1 -0
  30. package/dist/ai-capabilities/describe.js +31 -0
  31. package/dist/ai-capabilities/describe.js.map +1 -0
  32. package/dist/ai-capabilities/fsdeps.d.ts +3 -0
  33. package/dist/ai-capabilities/fsdeps.d.ts.map +1 -0
  34. package/dist/ai-capabilities/fsdeps.js +71 -0
  35. package/dist/ai-capabilities/fsdeps.js.map +1 -0
  36. package/dist/ai-capabilities/grok.d.ts +5 -0
  37. package/dist/ai-capabilities/grok.d.ts.map +1 -0
  38. package/dist/ai-capabilities/grok.js +145 -0
  39. package/dist/ai-capabilities/grok.js.map +1 -0
  40. package/dist/ai-capabilities/index.d.ts +4 -0
  41. package/dist/ai-capabilities/index.d.ts.map +1 -0
  42. package/dist/ai-capabilities/index.js +94 -0
  43. package/dist/ai-capabilities/index.js.map +1 -0
  44. package/dist/ai-capabilities/redact.d.ts +2 -0
  45. package/dist/ai-capabilities/redact.d.ts.map +1 -0
  46. package/dist/ai-capabilities/redact.js +27 -0
  47. package/dist/ai-capabilities/redact.js.map +1 -0
  48. package/dist/ai-capabilities/types.d.ts +11 -0
  49. package/dist/ai-capabilities/types.d.ts.map +1 -0
  50. package/dist/ai-capabilities/types.js +3 -0
  51. package/dist/ai-capabilities/types.js.map +1 -0
  52. package/dist/ai-launch.d.ts +35 -0
  53. package/dist/ai-launch.d.ts.map +1 -0
  54. package/dist/ai-launch.js +211 -0
  55. package/dist/ai-launch.js.map +1 -0
  56. package/dist/ai-session-detector.d.ts +19 -0
  57. package/dist/ai-session-detector.d.ts.map +1 -0
  58. package/dist/ai-session-detector.js +79 -0
  59. package/dist/ai-session-detector.js.map +1 -0
  60. package/dist/ai-sessions.d.ts +36 -0
  61. package/dist/ai-sessions.d.ts.map +1 -0
  62. package/dist/ai-sessions.js +309 -0
  63. package/dist/ai-sessions.js.map +1 -0
  64. package/dist/ai-status.d.ts +6 -0
  65. package/dist/ai-status.d.ts.map +1 -0
  66. package/dist/ai-status.js +40 -0
  67. package/dist/ai-status.js.map +1 -0
  68. package/dist/ai-transcript-locator.d.ts +35 -0
  69. package/dist/ai-transcript-locator.d.ts.map +1 -0
  70. package/dist/ai-transcript-locator.js +268 -0
  71. package/dist/ai-transcript-locator.js.map +1 -0
  72. package/dist/ai-transcript-tail.d.ts +17 -0
  73. package/dist/ai-transcript-tail.d.ts.map +1 -0
  74. package/dist/ai-transcript-tail.js +120 -0
  75. package/dist/ai-transcript-tail.js.map +1 -0
  76. package/dist/checklist.d.ts +20 -0
  77. package/dist/checklist.d.ts.map +1 -0
  78. package/dist/checklist.js +51 -0
  79. package/dist/checklist.js.map +1 -0
  80. package/dist/cli.d.ts +2 -0
  81. package/dist/cli.d.ts.map +1 -0
  82. package/dist/cli.js +1427 -0
  83. package/dist/cli.js.map +1 -0
  84. package/dist/command-runner.d.ts +15 -0
  85. package/dist/command-runner.d.ts.map +1 -0
  86. package/dist/command-runner.js +84 -0
  87. package/dist/command-runner.js.map +1 -0
  88. package/dist/config.d.ts +41 -0
  89. package/dist/config.d.ts.map +1 -0
  90. package/dist/config.js +152 -0
  91. package/dist/config.js.map +1 -0
  92. package/dist/cowork.d.ts +26 -0
  93. package/dist/cowork.d.ts.map +1 -0
  94. package/dist/cowork.js +370 -0
  95. package/dist/cowork.js.map +1 -0
  96. package/dist/fs-browser.d.ts +6 -0
  97. package/dist/fs-browser.d.ts.map +1 -0
  98. package/dist/fs-browser.js +61 -0
  99. package/dist/fs-browser.js.map +1 -0
  100. package/dist/has-command.d.ts +12 -0
  101. package/dist/has-command.d.ts.map +1 -0
  102. package/dist/has-command.js +24 -0
  103. package/dist/has-command.js.map +1 -0
  104. package/dist/heartbeat.d.ts +7 -0
  105. package/dist/heartbeat.d.ts.map +1 -0
  106. package/dist/heartbeat.js +50 -0
  107. package/dist/heartbeat.js.map +1 -0
  108. package/dist/index.d.ts +2 -0
  109. package/dist/index.d.ts.map +1 -0
  110. package/dist/index.js +56 -0
  111. package/dist/index.js.map +1 -0
  112. package/dist/port-scanner.d.ts +4 -0
  113. package/dist/port-scanner.d.ts.map +1 -0
  114. package/dist/port-scanner.js +75 -0
  115. package/dist/port-scanner.js.map +1 -0
  116. package/dist/project-scanner.d.ts +15 -0
  117. package/dist/project-scanner.d.ts.map +1 -0
  118. package/dist/project-scanner.js +333 -0
  119. package/dist/project-scanner.js.map +1 -0
  120. package/dist/pty-manager.d.ts +28 -0
  121. package/dist/pty-manager.d.ts.map +1 -0
  122. package/dist/pty-manager.js +506 -0
  123. package/dist/pty-manager.js.map +1 -0
  124. package/dist/service-installer.d.ts +95 -0
  125. package/dist/service-installer.d.ts.map +1 -0
  126. package/dist/service-installer.js +911 -0
  127. package/dist/service-installer.js.map +1 -0
  128. package/dist/single-instance.d.ts +20 -0
  129. package/dist/single-instance.d.ts.map +1 -0
  130. package/dist/single-instance.js +151 -0
  131. package/dist/single-instance.js.map +1 -0
  132. package/dist/ssh-local-network.d.ts +26 -0
  133. package/dist/ssh-local-network.d.ts.map +1 -0
  134. package/dist/ssh-local-network.js +169 -0
  135. package/dist/ssh-local-network.js.map +1 -0
  136. package/dist/terminal-detect.d.ts +52 -0
  137. package/dist/terminal-detect.d.ts.map +1 -0
  138. package/dist/terminal-detect.js +147 -0
  139. package/dist/terminal-detect.js.map +1 -0
  140. package/dist/terminal-markers.d.ts +52 -0
  141. package/dist/terminal-markers.d.ts.map +1 -0
  142. package/dist/terminal-markers.js +174 -0
  143. package/dist/terminal-markers.js.map +1 -0
  144. package/dist/tmux-manager.d.ts +35 -0
  145. package/dist/tmux-manager.d.ts.map +1 -0
  146. package/dist/tmux-manager.js +274 -0
  147. package/dist/tmux-manager.js.map +1 -0
  148. package/dist/update-check.d.ts +3 -0
  149. package/dist/update-check.d.ts.map +1 -0
  150. package/dist/update-check.js +202 -0
  151. package/dist/update-check.js.map +1 -0
  152. package/dist/websocket.d.ts +8 -0
  153. package/dist/websocket.d.ts.map +1 -0
  154. package/dist/websocket.js +472 -0
  155. package/dist/websocket.js.map +1 -0
  156. package/node_modules/@dialout/shared/README.md +16 -0
  157. package/node_modules/@dialout/shared/dist/ai-chat-prefs.d.ts +8 -0
  158. package/node_modules/@dialout/shared/dist/ai-chat-prefs.d.ts.map +1 -0
  159. package/node_modules/@dialout/shared/dist/ai-chat-prefs.js +41 -0
  160. package/node_modules/@dialout/shared/dist/capabilities.d.ts +25 -0
  161. package/node_modules/@dialout/shared/dist/capabilities.d.ts.map +1 -0
  162. package/node_modules/@dialout/shared/dist/capabilities.js +2 -0
  163. package/node_modules/@dialout/shared/dist/chat-blocks.d.ts +33 -0
  164. package/node_modules/@dialout/shared/dist/chat-blocks.d.ts.map +1 -0
  165. package/node_modules/@dialout/shared/dist/chat-blocks.js +61 -0
  166. package/node_modules/@dialout/shared/dist/command-filter.d.ts +4 -0
  167. package/node_modules/@dialout/shared/dist/command-filter.d.ts.map +1 -0
  168. package/node_modules/@dialout/shared/dist/command-filter.js +49 -0
  169. package/node_modules/@dialout/shared/dist/composer-behaviour.d.ts +6 -0
  170. package/node_modules/@dialout/shared/dist/composer-behaviour.d.ts.map +1 -0
  171. package/node_modules/@dialout/shared/dist/composer-behaviour.js +24 -0
  172. package/node_modules/@dialout/shared/dist/events.d.ts +37 -0
  173. package/node_modules/@dialout/shared/dist/events.d.ts.map +1 -0
  174. package/node_modules/@dialout/shared/dist/events.js +13 -0
  175. package/node_modules/@dialout/shared/dist/index.d.ts +21 -0
  176. package/node_modules/@dialout/shared/dist/index.d.ts.map +1 -0
  177. package/node_modules/@dialout/shared/dist/index.js +37 -0
  178. package/node_modules/@dialout/shared/dist/kinds.d.ts +2 -0
  179. package/node_modules/@dialout/shared/dist/kinds.d.ts.map +1 -0
  180. package/node_modules/@dialout/shared/dist/kinds.js +2 -0
  181. package/node_modules/@dialout/shared/dist/notify.d.ts +3 -0
  182. package/node_modules/@dialout/shared/dist/notify.d.ts.map +1 -0
  183. package/node_modules/@dialout/shared/dist/notify.js +31 -0
  184. package/node_modules/@dialout/shared/dist/permission.d.ts +4 -0
  185. package/node_modules/@dialout/shared/dist/permission.d.ts.map +1 -0
  186. package/node_modules/@dialout/shared/dist/permission.js +8 -0
  187. package/node_modules/@dialout/shared/dist/scroll-pin.d.ts +3 -0
  188. package/node_modules/@dialout/shared/dist/scroll-pin.d.ts.map +1 -0
  189. package/node_modules/@dialout/shared/dist/scroll-pin.js +11 -0
  190. package/node_modules/@dialout/shared/dist/session.d.ts +19 -0
  191. package/node_modules/@dialout/shared/dist/session.d.ts.map +1 -0
  192. package/node_modules/@dialout/shared/dist/session.js +6 -0
  193. package/node_modules/@dialout/shared/dist/terminal-name.d.ts +25 -0
  194. package/node_modules/@dialout/shared/dist/terminal-name.d.ts.map +1 -0
  195. package/node_modules/@dialout/shared/dist/terminal-name.js +63 -0
  196. package/node_modules/@dialout/shared/dist/tool-appearance.d.ts +9 -0
  197. package/node_modules/@dialout/shared/dist/tool-appearance.d.ts.map +1 -0
  198. package/node_modules/@dialout/shared/dist/tool-appearance.js +30 -0
  199. package/node_modules/@dialout/shared/package.json +37 -0
  200. package/node_modules/@dialout/shared/src/ai-chat-prefs.test.ts +40 -0
  201. package/node_modules/@dialout/shared/src/ai-chat-prefs.ts +39 -0
  202. package/node_modules/@dialout/shared/src/capabilities.ts +30 -0
  203. package/node_modules/@dialout/shared/src/chat-blocks.test.ts +65 -0
  204. package/node_modules/@dialout/shared/src/chat-blocks.ts +79 -0
  205. package/node_modules/@dialout/shared/src/command-filter.test.ts +76 -0
  206. package/node_modules/@dialout/shared/src/command-filter.ts +45 -0
  207. package/node_modules/@dialout/shared/src/composer-behaviour.test.ts +31 -0
  208. package/node_modules/@dialout/shared/src/composer-behaviour.ts +22 -0
  209. package/node_modules/@dialout/shared/src/events.ts +27 -0
  210. package/node_modules/@dialout/shared/src/index.ts +32 -0
  211. package/node_modules/@dialout/shared/src/kinds.ts +5 -0
  212. package/node_modules/@dialout/shared/src/notify.test.ts +49 -0
  213. package/node_modules/@dialout/shared/src/notify.ts +30 -0
  214. package/node_modules/@dialout/shared/src/permission.ts +10 -0
  215. package/node_modules/@dialout/shared/src/scroll-pin.test.ts +23 -0
  216. package/node_modules/@dialout/shared/src/scroll-pin.ts +13 -0
  217. package/node_modules/@dialout/shared/src/session.ts +25 -0
  218. package/node_modules/@dialout/shared/src/terminal-name.ts +82 -0
  219. package/node_modules/@dialout/shared/src/tool-appearance.test.ts +41 -0
  220. package/node_modules/@dialout/shared/src/tool-appearance.ts +39 -0
  221. package/package.json +54 -14
  222. package/scripts/postinstall.js +79 -0
  223. package/scripts/prepack.js +45 -0
  224. package/bin/dialout.js +0 -13
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.codexAdapter = void 0;
4
+ const types_1 = require("./types");
5
+ // Codex writes ~/.codex/sessions/YYYY/MM/DD/rollout-<ts>-<uuid>.jsonl as
6
+ // { timestamp, type, payload } where type is
7
+ // session_meta | turn_context | event_msg | response_item | world_state.
8
+ //
9
+ // Everything the UI shows comes from response_item. Measured on a real 128-line
10
+ // rollout, its payload types are:
11
+ //
12
+ // message 19 role: developer 7 | user 3 | assistant 9
13
+ // reasoning 20 summary EMPTY on all 20; text is encrypted
14
+ // custom_tool_call 20 status 'completed' on all 20
15
+ // custom_tool_call_output 20
16
+ // function_call 1
17
+ // function_call_output 1
18
+ //
19
+ // v1 of this adapter emitted only `message` and dropped the other 60 records.
20
+ // That was not merely shallow: deriveStatus() decides 'waiting_approval' by
21
+ // finding a tool_call with no matching tool_result, so a Codex session could
22
+ // never report that status at all — it only ever read working/waiting_input/idle.
23
+ // Tool calls and their outputs are paired by `call_id`, NOT by `id`. The two
24
+ // records carry different ids for the same call — `ctc_…` on the call and
25
+ // `ctco_…` on the output — so pairing on `id` silently never matches and every
26
+ // call looks unresolved forever, which pins the session at 'waiting_approval'.
27
+ function callIdOf(payload) {
28
+ return String(payload.call_id || payload.id || '');
29
+ }
30
+ // Content and output blocks are [{type, text}] — but not every block has text:
31
+ // a real output carried 39 input_text blocks and 2 input_image blocks, the
32
+ // latter holding an image_url and no text at all. Joining `b.text` blindly is
33
+ // safe only because a missing one yields ''.
34
+ function textOf(content) {
35
+ if (typeof content === 'string')
36
+ return content;
37
+ if (Array.isArray(content)) {
38
+ return content.map((b) => (typeof b?.text === 'string' ? b.text : '')).join('');
39
+ }
40
+ return '';
41
+ }
42
+ exports.codexAdapter = {
43
+ toEvents(record) {
44
+ const rec = record;
45
+ if (!rec || typeof rec !== 'object')
46
+ return [];
47
+ if (rec.type !== 'response_item')
48
+ return [];
49
+ const payload = rec.payload;
50
+ if (!payload || typeof payload !== 'object')
51
+ return [];
52
+ const at = typeof rec.timestamp === 'string' ? rec.timestamp : '';
53
+ switch (payload.type) {
54
+ case 'message': {
55
+ // `developer` is Codex's own instruction block — sandbox permissions,
56
+ // base instructions — injected into the conversation, and there were 7
57
+ // of them in a 19-message transcript. v1 mapped every non-user role to
58
+ // 'assistant', so all 7 rendered as things the agent had said.
59
+ if (payload.role !== 'user' && payload.role !== 'assistant')
60
+ return [];
61
+ const text = textOf(payload.content);
62
+ if (!text)
63
+ return [];
64
+ return [{
65
+ kind: 'message',
66
+ role: payload.role,
67
+ text,
68
+ id: String(payload.id || ''),
69
+ at,
70
+ }];
71
+ }
72
+ case 'reasoning': {
73
+ // Codex encrypts its reasoning: `summary` was an empty array on all 20
74
+ // records and the text lives in `encrypted_content`, which we cannot
75
+ // read and must not surface as a blank thinking bubble. Emit only when
76
+ // a summary actually carries text, so this starts working by itself if
77
+ // Codex ever stops encrypting it.
78
+ const text = textOf(payload.summary);
79
+ if (!text)
80
+ return [];
81
+ return [{ kind: 'thinking', text, id: String(payload.id || ''), at }];
82
+ }
83
+ case 'custom_tool_call': {
84
+ // `input` is a free-form string (a JS snippet for the exec tool), not
85
+ // JSON, so it is passed through rather than parsed.
86
+ const input = payload.input;
87
+ return [{
88
+ kind: 'tool_call',
89
+ name: String(payload.name || 'tool'),
90
+ summary: (0, types_1.preview)(typeof input === 'string' ? input : JSON.stringify(input ?? '')),
91
+ input,
92
+ id: callIdOf(payload),
93
+ at,
94
+ }];
95
+ }
96
+ case 'function_call': {
97
+ // `arguments` IS a JSON string here. Parse it for structured input, but
98
+ // never let malformed JSON drop the call — the raw string still tells
99
+ // the user what ran.
100
+ let input = payload.arguments;
101
+ if (typeof payload.arguments === 'string') {
102
+ try {
103
+ input = JSON.parse(payload.arguments);
104
+ }
105
+ catch { /* keep the raw string */ }
106
+ }
107
+ return [{
108
+ kind: 'tool_call',
109
+ name: String(payload.name || 'tool'),
110
+ summary: (0, types_1.preview)(typeof payload.arguments === 'string'
111
+ ? payload.arguments
112
+ : JSON.stringify(payload.arguments ?? '')),
113
+ input,
114
+ id: callIdOf(payload),
115
+ at,
116
+ }];
117
+ }
118
+ case 'custom_tool_call_output':
119
+ case 'function_call_output': {
120
+ return [{
121
+ kind: 'tool_result',
122
+ forId: callIdOf(payload),
123
+ // No failure shape was observable: `status` appears only on the CALL
124
+ // and was 'completed' on all 20, and outputs carry no error field.
125
+ // Reporting ok:false on a guess would mark healthy results as errors.
126
+ ok: true,
127
+ preview: (0, types_1.preview)(textOf(payload.output)),
128
+ at,
129
+ }];
130
+ }
131
+ default:
132
+ return [];
133
+ }
134
+ },
135
+ title(record) {
136
+ const rec = record;
137
+ if (!rec || typeof rec !== 'object')
138
+ return null;
139
+ // Codex records no user-facing title, so the folder is the best available.
140
+ if (rec.type === 'session_meta' && typeof rec.payload?.cwd === 'string') {
141
+ const parts = rec.payload.cwd.split('/').filter(Boolean);
142
+ return parts[parts.length - 1] || null;
143
+ }
144
+ return null;
145
+ },
146
+ };
147
+ //# sourceMappingURL=codex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/ai-adapters/codex.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { AiAdapter } from './types';
2
+ export declare const grokAdapter: AiAdapter;
3
+ //# sourceMappingURL=grok.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grok.d.ts","sourceRoot":"","sources":["../../src/ai-adapters/grok.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAoB,MAAM,SAAS,CAAC;AAmEtD,eAAO,MAAM,WAAW,EAAE,SA4FzB,CAAC"}
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.grokAdapter = void 0;
4
+ const types_1 = require("./types");
5
+ // Grok CLI writes a directory per session, not a single file:
6
+ //
7
+ // ~/.grok/sessions/<encodeURIComponent(cwd)>/<session-uuid>/
8
+ // chat_history.jsonl the conversation
9
+ // events.jsonl telemetry
10
+ // summary.json title, cwd, timestamps
11
+ //
12
+ // We tail chat_history.jsonl. events.jsonl is tempting — it is the only file
13
+ // with timestamps, and it carries tool outcomes and permission decisions — but
14
+ // it is telemetry, not conversation: measured on a real session, 1843 of its
15
+ // 2011 records were `phase_changed`, and it contains no message text at all.
16
+ // Status is derived from the event stream and file growth (see ai-status.ts),
17
+ // which chat_history drives correctly on its own.
18
+ //
19
+ // Record types, measured on a real 57-line transcript 2026-08-21:
20
+ // system 1 the system prompt
21
+ // user 4 see the prompt_index rule below
22
+ // reasoning 16 { id, summary: [{type, text}], encrypted_content, status }
23
+ // assistant 16 { content: string, tool_calls: [{id, name, arguments}] }
24
+ // tool_result 20 { tool_call_id, content: string }
25
+ // chat_history.jsonl records carry NO timestamp — only events.jsonl does. The
26
+ // AiEvent contract allows an empty `at` (the Codex adapter does the same for
27
+ // ids it cannot supply), the UI does not render it, and deriveStatus() uses
28
+ // file growth rather than record time, so nothing downstream needs it.
29
+ const NO_TIMESTAMP = '';
30
+ function textOf(content) {
31
+ if (typeof content === 'string')
32
+ return content;
33
+ if (Array.isArray(content)) {
34
+ return content.map((b) => (typeof b?.text === 'string' ? b.text : '')).join('');
35
+ }
36
+ return '';
37
+ }
38
+ // Grok wraps the real prompt in <user_query>…</user_query> and then APPENDS a
39
+ // <system-reminder> block (attached files, skill listings) after the closing
40
+ // tag, inside the same record. Measured: a 776-character prompt record whose
41
+ // last 90 characters are `</attached_files>\n\n</system-reminder>`.
42
+ //
43
+ // So the match must NOT be anchored to the end of the string — an end-anchored
44
+ // pattern never fires on a real record, and both the literal tags and the
45
+ // appended reminder end up in the chat bubble and in the session title. Taking
46
+ // the first matched pair yields exactly what the human typed and drops the
47
+ // appended block as a side effect. Text with no wrapper is returned untouched.
48
+ function unwrapQuery(text) {
49
+ const m = text.match(/<user_query>\n?([\s\S]*?)\n?<\/user_query>/);
50
+ return m ? m[1] : text;
51
+ }
52
+ // Only one of the four `user` records in a real transcript is something the
53
+ // human typed. The other three are context grok injects into the conversation:
54
+ //
55
+ // prompt_index=undefined, synthetic_reason=undefined -> <user_info> preamble
56
+ // prompt_index=undefined, synthetic_reason='system_reminder' -> injected notice
57
+ // prompt_index=0, synthetic_reason=undefined -> the actual prompt
58
+ //
59
+ // So a real prompt is exactly a record carrying a numeric prompt_index. Testing
60
+ // `!synthetic_reason` instead would let the <user_info> preamble through, and
61
+ // that block is the first thing in every session — it would become every
62
+ // session's title and first chat bubble.
63
+ function isRealPrompt(rec) {
64
+ return typeof rec.prompt_index === 'number';
65
+ }
66
+ exports.grokAdapter = {
67
+ toEvents(record) {
68
+ const rec = record;
69
+ if (!rec || typeof rec !== 'object')
70
+ return [];
71
+ switch (rec.type) {
72
+ case 'user': {
73
+ if (!isRealPrompt(rec))
74
+ return [];
75
+ const text = unwrapQuery(textOf(rec.content));
76
+ if (!text)
77
+ return [];
78
+ return [{
79
+ kind: 'message', role: 'user', text,
80
+ id: `prompt-${rec.prompt_index}`, at: NO_TIMESTAMP,
81
+ }];
82
+ }
83
+ case 'assistant': {
84
+ const out = [];
85
+ const text = textOf(rec.content);
86
+ // An assistant turn that only calls tools has empty content; emitting a
87
+ // blank bubble for it would break up the transcript for no reason.
88
+ if (text) {
89
+ out.push({
90
+ kind: 'message', role: 'assistant', text,
91
+ id: '', at: NO_TIMESTAMP,
92
+ });
93
+ }
94
+ for (const call of Array.isArray(rec.tool_calls) ? rec.tool_calls : []) {
95
+ if (!call || typeof call !== 'object')
96
+ continue;
97
+ // `arguments` is a JSON *string*, not an object. Parse it so the UI
98
+ // gets structured input, but never let malformed JSON kill the event:
99
+ // the raw string is still more useful than dropping the tool call.
100
+ let input = call.arguments;
101
+ if (typeof call.arguments === 'string') {
102
+ try {
103
+ input = JSON.parse(call.arguments);
104
+ }
105
+ catch { /* keep the raw string */ }
106
+ }
107
+ out.push({
108
+ kind: 'tool_call',
109
+ name: String(call.name || 'tool'),
110
+ summary: (0, types_1.preview)(typeof call.arguments === 'string'
111
+ ? call.arguments
112
+ : JSON.stringify(call.arguments ?? '')),
113
+ input,
114
+ id: String(call.id || ''),
115
+ at: NO_TIMESTAMP,
116
+ });
117
+ }
118
+ return out;
119
+ }
120
+ case 'reasoning': {
121
+ const text = textOf(rec.summary);
122
+ if (!text)
123
+ return [];
124
+ return [{
125
+ kind: 'thinking', text, id: String(rec.id || ''), at: NO_TIMESTAMP,
126
+ }];
127
+ }
128
+ case 'tool_result': {
129
+ return [{
130
+ kind: 'tool_result',
131
+ forId: String(rec.tool_call_id || ''),
132
+ // chat_history.jsonl records no outcome — only events.jsonl does, as
133
+ // `tool_completed.outcome`. All 23 outcomes in the measured session
134
+ // were 'success', so no failure shape was observable to key off. A
135
+ // wrong `ok: false` would mark healthy results as errors in the UI,
136
+ // so report success and let the result text speak for itself.
137
+ ok: true,
138
+ preview: (0, types_1.preview)(textOf(rec.content)),
139
+ at: NO_TIMESTAMP,
140
+ }];
141
+ }
142
+ // 'system' is the system prompt — 6 KB of instructions the user never
143
+ // wrote and does not want to read back.
144
+ default:
145
+ return [];
146
+ }
147
+ },
148
+ // chat_history.jsonl has no title record; summary.json holds grok's own
149
+ // ("session_summary") but is a different file this tail never reads. The
150
+ // first thing the human typed is the best title available from the stream,
151
+ // and it matches how launch mode titles its sessions (ai-launch.ts).
152
+ title(record) {
153
+ const rec = record;
154
+ if (!rec || typeof rec !== 'object')
155
+ return null;
156
+ if (rec.type !== 'user' || !isRealPrompt(rec))
157
+ return null;
158
+ if (rec.prompt_index !== 0)
159
+ return null; // only the FIRST prompt names the session
160
+ const text = unwrapQuery(textOf(rec.content)).replace(/\s+/g, ' ').trim();
161
+ return text ? text.slice(0, 60) : null;
162
+ },
163
+ };
164
+ //# sourceMappingURL=grok.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grok.js","sourceRoot":"","sources":["../../src/ai-adapters/grok.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { AiKind } from '../ai-session-detector';
2
+ import { AiAdapter } from './types';
3
+ export declare function adapterFor(kind: AiKind): AiAdapter;
4
+ export * from './types';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ai-adapters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAWpC,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAElD;AAED,cAAc,SAAS,CAAC"}
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.adapterFor = adapterFor;
18
+ const claude_1 = require("./claude");
19
+ const codex_1 = require("./codex");
20
+ const grok_1 = require("./grok");
21
+ const ADAPTERS = {
22
+ claude: claude_1.claudeAdapter,
23
+ codex: codex_1.codexAdapter,
24
+ grok: grok_1.grokAdapter,
25
+ };
26
+ function adapterFor(kind) {
27
+ return ADAPTERS[kind];
28
+ }
29
+ __exportStar(require("./types"), exports);
30
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ai-adapters/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAYA,gCAEC;AAZD,qCAAyC;AACzC,mCAAuC;AACvC,iCAAqC;AAErC,MAAM,QAAQ,GAA8B;IAC1C,MAAM,EAAE,sBAAa;IACrB,KAAK,EAAE,oBAAY;IACnB,IAAI,EAAE,kBAAW;CAClB,CAAC;AAEF,SAAgB,UAAU,CAAC,IAAY;IACrC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC;AAED,0CAAwB"}
@@ -0,0 +1,3 @@
1
+ export type { AiStatus, AiEvent, AiAdapter } from '@dialout/shared';
2
+ export { PREVIEW_LIMIT, preview } from '@dialout/shared';
3
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/ai-adapters/types.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.preview = exports.PREVIEW_LIMIT = void 0;
4
+ var shared_1 = require("@dialout/shared");
5
+ Object.defineProperty(exports, "PREVIEW_LIMIT", { enumerable: true, get: function () { return shared_1.PREVIEW_LIMIT; } });
6
+ Object.defineProperty(exports, "preview", { enumerable: true, get: function () { return shared_1.preview; } });
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/ai-adapters/types.ts"],"names":[],"mappings":";;;AACA,0CAAyD;AAAhD,uGAAA,aAAa,OAAA;AAAE,iGAAA,OAAO,OAAA"}
@@ -0,0 +1,4 @@
1
+ import type { AiCommand, McpServerInfo, CapabilityDeps } from './types';
2
+ export declare function claudeCommands(cwd: string, deps?: CapabilityDeps): AiCommand[];
3
+ export declare function claudeMcpServers(cwd: string, deps?: CapabilityDeps): McpServerInfo[];
4
+ //# sourceMappingURL=claude.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/ai-capabilities/claude.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAiFxE,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,cAAmB,GAAG,SAAS,EAAE,CAclF;AA4BD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,cAAmB,GAAG,aAAa,EAAE,CAuBxF"}
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.claudeCommands = claudeCommands;
37
+ exports.claudeMcpServers = claudeMcpServers;
38
+ const path = __importStar(require("path"));
39
+ const describe_1 = require("./describe");
40
+ const redact_1 = require("./redact");
41
+ const fsdeps_1 = require("./fsdeps");
42
+ function safe(fn, fallback) {
43
+ try {
44
+ const v = fn();
45
+ return v === null || v === undefined ? fallback : v;
46
+ }
47
+ catch {
48
+ return fallback;
49
+ }
50
+ }
51
+ function readCommandDir(dir, source, prefix, d) {
52
+ const out = [];
53
+ for (const entry of safe(() => d.readDir(dir), [])) {
54
+ if (!entry.endsWith('.md'))
55
+ continue;
56
+ const body = safe(() => d.readFile(path.join(dir, entry)), null);
57
+ out.push({
58
+ name: prefix + entry.slice(0, -3),
59
+ description: (0, describe_1.describeCommand)(body || ''),
60
+ source,
61
+ });
62
+ }
63
+ return out;
64
+ }
65
+ // Plugin command directories, measured rather than assumed. Three shapes
66
+ // really exist under ~/.claude/plugins/marketplaces:
67
+ //
68
+ // <marketplace>/commands (marketplace is the plugin)
69
+ // <marketplace>/<plugin>/commands (e.g. pdf-viewer)
70
+ // <marketplace>/plugins/<plugin>/commands (the common case, 25 of 32)
71
+ // <marketplace>/external_plugins/<plugin>/commands
72
+ //
73
+ // A generic "find any directory named commands" walk looked tidier and was
74
+ // wrong twice over: it picked up <marketplace>/.claude/commands — a marketplace
75
+ // repo's OWN project commands, which the user's CLI does not expose — and
76
+ // namespaced them `.claude:`. It also matched impeccable/bin/commands, which
77
+ // holds skills.mjs and no slash commands at all.
78
+ const PLUGIN_CONTAINERS = ['plugins', 'external_plugins'];
79
+ function pluginCommandDirs(marketplaces, d) {
80
+ const out = [];
81
+ for (const mp of safe(() => d.readDir(marketplaces), [])) {
82
+ if (mp.startsWith('.'))
83
+ continue;
84
+ const mpDir = path.join(marketplaces, mp);
85
+ if (!safe(() => d.isDir(mpDir), false))
86
+ continue;
87
+ if (safe(() => d.isDir(path.join(mpDir, 'commands')), false)) {
88
+ out.push({ dir: path.join(mpDir, 'commands'), name: mp });
89
+ }
90
+ for (const child of safe(() => d.readDir(mpDir), [])) {
91
+ // Dot-directories are the repo's own tooling, never a published plugin.
92
+ if (child.startsWith('.') || child === 'commands')
93
+ continue;
94
+ const childDir = path.join(mpDir, child);
95
+ if (!safe(() => d.isDir(childDir), false))
96
+ continue;
97
+ if (PLUGIN_CONTAINERS.includes(child)) {
98
+ for (const plugin of safe(() => d.readDir(childDir), [])) {
99
+ if (plugin.startsWith('.'))
100
+ continue;
101
+ const cmds = path.join(childDir, plugin, 'commands');
102
+ if (safe(() => d.isDir(cmds), false))
103
+ out.push({ dir: cmds, name: plugin });
104
+ }
105
+ }
106
+ else if (safe(() => d.isDir(path.join(childDir, 'commands')), false)) {
107
+ out.push({ dir: path.join(childDir, 'commands'), name: child });
108
+ }
109
+ }
110
+ }
111
+ return out;
112
+ }
113
+ function claudeCommands(cwd, deps = {}) {
114
+ const d = (0, fsdeps_1.resolveDeps)(deps);
115
+ const home = d.homeDir();
116
+ const out = [];
117
+ out.push(...readCommandDir(path.join(home, '.claude', 'commands'), 'user', '', d));
118
+ out.push(...readCommandDir(path.join(cwd, '.claude', 'commands'), 'project', '', d));
119
+ const marketplaces = path.join(home, '.claude', 'plugins', 'marketplaces');
120
+ for (const { dir, name } of pluginCommandDirs(marketplaces, d)) {
121
+ out.push(...readCommandDir(dir, 'plugin', `${name}:`, d));
122
+ }
123
+ return out;
124
+ }
125
+ function readJson(file, d) {
126
+ const raw = safe(() => d.readFile(file), null);
127
+ if (!raw)
128
+ return null;
129
+ try {
130
+ return JSON.parse(raw);
131
+ }
132
+ catch {
133
+ return null;
134
+ }
135
+ }
136
+ function toServer(name, cfg, scope, origin) {
137
+ const http = !!(cfg && (cfg.url || cfg.type === 'http' || cfg.type === 'sse'));
138
+ return {
139
+ name,
140
+ scope,
141
+ origin,
142
+ transport: http ? 'http' : 'stdio',
143
+ // Claude has no explicit disable flag; absent means enabled.
144
+ enabled: cfg?.enabled !== false,
145
+ command: http ? undefined : (cfg?.command ? String(cfg.command) : undefined),
146
+ args: http ? undefined : (0, redact_1.redactArgs)(cfg?.args),
147
+ };
148
+ }
149
+ // The four locations are measured; Claude's runtime precedence between them is
150
+ // NOT. So this does not claim to reproduce resolution — it reports each server
151
+ // with the scope it came from, and on a name collision shows the narrower one.
152
+ // Later entries here win, so project sources come last.
153
+ function claudeMcpServers(cwd, deps = {}) {
154
+ const d = (0, fsdeps_1.resolveDeps)(deps);
155
+ const home = d.homeDir();
156
+ const merged = new Map();
157
+ const add = (obj, scope, origin) => {
158
+ if (!obj || typeof obj !== 'object')
159
+ return;
160
+ for (const [name, cfg] of Object.entries(obj)) {
161
+ merged.set(name, toServer(name, cfg, scope, origin));
162
+ }
163
+ };
164
+ const claudeJsonPath = path.join(home, '.claude.json');
165
+ const claudeJson = readJson(claudeJsonPath, d);
166
+ const settingsPath = path.join(home, '.claude', 'settings.json');
167
+ const mcpJsonPath = path.join(cwd, '.mcp.json');
168
+ add(claudeJson?.mcpServers, 'global', claudeJsonPath);
169
+ add(readJson(settingsPath, d)?.mcpServers, 'global', settingsPath);
170
+ add(readJson(mcpJsonPath, d)?.mcpServers, 'project', mcpJsonPath);
171
+ add(claudeJson?.projects?.[cwd]?.mcpServers, 'project', claudeJsonPath);
172
+ return Array.from(merged.values());
173
+ }
174
+ //# sourceMappingURL=claude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/ai-capabilities/claude.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function describeCommand(markdown: string): string;
2
+ //# sourceMappingURL=describe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"describe.d.ts","sourceRoot":"","sources":["../../src/ai-capabilities/describe.ts"],"names":[],"mappings":"AAUA,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAmBxD"}
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.describeCommand = describeCommand;
4
+ const MAX = 160;
5
+ function clamp(s) {
6
+ const t = s.trim().replace(/\s+/g, ' ');
7
+ return t.length <= MAX ? t : `${t.slice(0, MAX - 1)}…`;
8
+ }
9
+ // Frontmatter is NOT reliable in real command files — ~/.claude/commands/seo.md
10
+ // opens with a bare `# SEO Machine`. So this falls all the way through to the
11
+ // first non-empty line rather than returning nothing.
12
+ function describeCommand(markdown) {
13
+ const text = String(markdown || '');
14
+ // Closed frontmatter only: an unterminated block is body text, not metadata.
15
+ const fm = text.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n/);
16
+ if (fm) {
17
+ const d = fm[1].match(/^description:\s*(.+)$/m);
18
+ if (d)
19
+ return clamp(d[1].replace(/^["']|["']$/g, ''));
20
+ }
21
+ const body = fm ? text.slice(fm[0].length) : text;
22
+ const heading = body.match(/^#{1,6}\s+(.+)$/m);
23
+ if (heading)
24
+ return clamp(heading[1]);
25
+ for (const line of body.split('\n')) {
26
+ if (line.trim())
27
+ return clamp(line);
28
+ }
29
+ return '';
30
+ }
31
+ //# sourceMappingURL=describe.js.map