@agi-fans/dsh-tui 0.15.0 → 0.17.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 (114) hide show
  1. package/lib/CHANGELOG.md +47 -1
  2. package/lib/chrome/diff-render.js +12 -0
  3. package/lib/chrome/diff-render.js.map +1 -1
  4. package/lib/chrome/main-screen-renderer.js +21 -5
  5. package/lib/chrome/main-screen-renderer.js.map +1 -1
  6. package/lib/chrome/markdown.js +5 -2
  7. package/lib/chrome/markdown.js.map +1 -1
  8. package/lib/chrome/renderer.d.ts +8 -0
  9. package/lib/chrome/renderer.js.map +1 -1
  10. package/lib/chrome/status-line.d.ts +1 -1
  11. package/lib/chrome/status-line.js +38 -9
  12. package/lib/chrome/status-line.js.map +1 -1
  13. package/lib/chrome/theme.d.ts +9 -2
  14. package/lib/chrome/theme.js +60 -12
  15. package/lib/chrome/theme.js.map +1 -1
  16. package/lib/chrome/tool-args.d.ts +9 -0
  17. package/lib/chrome/tool-args.js +20 -0
  18. package/lib/chrome/tool-args.js.map +1 -0
  19. package/lib/chrome/tool-renderers.d.ts +2 -0
  20. package/lib/chrome/tool-renderers.js +101 -9
  21. package/lib/chrome/tool-renderers.js.map +1 -1
  22. package/lib/chrome/welcome-tips.js +1 -0
  23. package/lib/chrome/welcome-tips.js.map +1 -1
  24. package/lib/chrome/width.d.ts +19 -1
  25. package/lib/chrome/width.js +135 -41
  26. package/lib/chrome/width.js.map +1 -1
  27. package/lib/commands/session.js +5 -4
  28. package/lib/commands/session.js.map +1 -1
  29. package/lib/definition.d.ts +13 -1
  30. package/lib/runtime/composer-images.d.ts +44 -0
  31. package/lib/runtime/composer-images.js +149 -0
  32. package/lib/runtime/composer-images.js.map +1 -0
  33. package/lib/runtime/herdr-agent.d.ts +95 -0
  34. package/lib/runtime/herdr-agent.js +258 -0
  35. package/lib/runtime/herdr-agent.js.map +1 -0
  36. package/lib/runtime/plain-tui.d.ts +34 -0
  37. package/lib/runtime/plain-tui.js +119 -0
  38. package/lib/runtime/plain-tui.js.map +1 -0
  39. package/lib/runtime/provider-local.d.ts +9 -4
  40. package/lib/runtime/provider-local.js +180 -275
  41. package/lib/runtime/provider-local.js.map +1 -1
  42. package/lib/runtime/tool-presentation.js +15 -0
  43. package/lib/runtime/tool-presentation.js.map +1 -1
  44. package/lib/session/content-text.d.ts +12 -0
  45. package/lib/session/content-text.js +13 -0
  46. package/lib/session/content-text.js.map +1 -0
  47. package/lib/session/history-store.js.map +1 -0
  48. package/lib/session/interaction-adapter.d.ts +10 -0
  49. package/lib/session/interaction-adapter.js +12 -1
  50. package/lib/session/interaction-adapter.js.map +1 -1
  51. package/lib/session/json-file.d.ts +5 -0
  52. package/lib/session/json-file.js +21 -0
  53. package/lib/session/json-file.js.map +1 -0
  54. package/lib/session/model-favorites.js +15 -25
  55. package/lib/session/model-favorites.js.map +1 -1
  56. package/lib/session/release-notes.js +1 -18
  57. package/lib/session/release-notes.js.map +1 -1
  58. package/lib/session/session-controller.js +65 -138
  59. package/lib/session/session-controller.js.map +1 -1
  60. package/lib/session/session-library.js +4 -14
  61. package/lib/session/session-library.js.map +1 -1
  62. package/lib/session/subagent-roster.d.ts +2 -9
  63. package/lib/session/subagent-roster.js +39 -74
  64. package/lib/session/subagent-roster.js.map +1 -1
  65. package/lib/session/subagent-tracker.d.ts +58 -0
  66. package/lib/session/subagent-tracker.js +129 -0
  67. package/lib/session/subagent-tracker.js.map +1 -0
  68. package/lib/session/update-check.js +2 -15
  69. package/lib/session/update-check.js.map +1 -1
  70. package/lib/session/version-compare.d.ts +3 -0
  71. package/lib/session/version-compare.js +21 -0
  72. package/lib/session/version-compare.js.map +1 -0
  73. package/lib/views/agent-hub.d.ts +3 -0
  74. package/lib/views/agent-hub.js +40 -4
  75. package/lib/views/agent-hub.js.map +1 -1
  76. package/lib/views/copy-selector.d.ts +3 -0
  77. package/lib/views/copy-selector.js +26 -6
  78. package/lib/views/copy-selector.js.map +1 -1
  79. package/lib/views/event-views.d.ts +11 -254
  80. package/lib/views/event-views.js +25 -932
  81. package/lib/views/event-views.js.map +1 -1
  82. package/lib/views/history-search.d.ts +3 -0
  83. package/lib/views/history-search.js +40 -4
  84. package/lib/views/history-search.js.map +1 -1
  85. package/lib/views/hotkey-format.d.ts +39 -0
  86. package/lib/views/hotkey-format.js +42 -0
  87. package/lib/views/hotkey-format.js.map +1 -0
  88. package/lib/views/hotkeys.d.ts +3 -0
  89. package/lib/views/hotkeys.js +33 -3
  90. package/lib/views/hotkeys.js.map +1 -1
  91. package/lib/views/prompt-selector.d.ts +3 -0
  92. package/lib/views/prompt-selector.js +46 -7
  93. package/lib/views/prompt-selector.js.map +1 -1
  94. package/lib/views/settings-list.d.ts +3 -0
  95. package/lib/views/settings-list.js +47 -16
  96. package/lib/views/settings-list.js.map +1 -1
  97. package/lib/views/streaming-reveal.js +56 -17
  98. package/lib/views/streaming-reveal.js.map +1 -1
  99. package/lib/views/trajectory.d.ts +15 -5
  100. package/lib/views/trajectory.js +64 -7
  101. package/lib/views/trajectory.js.map +1 -1
  102. package/lib/views/transcript-render.d.ts +179 -0
  103. package/lib/views/transcript-render.js +916 -0
  104. package/lib/views/transcript-render.js.map +1 -0
  105. package/lib/views/transcript-search.d.ts +3 -0
  106. package/lib/views/transcript-search.js +24 -3
  107. package/lib/views/transcript-search.js.map +1 -1
  108. package/lib/views/transcript-types.d.ts +104 -0
  109. package/lib/views/transcript-types.js +53 -0
  110. package/lib/views/transcript-types.js.map +1 -0
  111. package/package.json +34 -33
  112. package/lib/views/history-store.js.map +0 -1
  113. /package/lib/{views → session}/history-store.d.ts +0 -0
  114. /package/lib/{views → session}/history-store.js +0 -0
@@ -0,0 +1,149 @@
1
+ /**
2
+ * ComposerImages — owns the image-draft list and its `[Image #n]` markers
3
+ * inside the composer text.
4
+ *
5
+ * Draft ownership only: inserting, removing at the cursor, renumbering after
6
+ * edits, and dropping drafts whose marker disappeared. Paste routing, key
7
+ * decoding, and the prompt/settings/search branches that decide whether a
8
+ * paste is an image at all stay in the provider.
9
+ */
10
+ import { imageMarker, probeImageDimensions } from "../input/image-paste.js";
11
+ export class ComposerImages {
12
+ #deps;
13
+ #images = [];
14
+ #validate;
15
+ constructor(deps) {
16
+ this.#deps = deps;
17
+ }
18
+ get count() {
19
+ return this.#images.length;
20
+ }
21
+ /** Fresh copies for a submission snapshot. */
22
+ copies() {
23
+ return this.#images.map(image => ({ ...image }));
24
+ }
25
+ setValidator(validate) {
26
+ this.#validate = validate;
27
+ }
28
+ /**
29
+ * Run the Harness image-admission check for one paste candidate. A refusal
30
+ * becomes an error notice and skips the draft, instead of failing the whole
31
+ * submission after the user has typed a prompt around it.
32
+ */
33
+ async admit(image) {
34
+ if (this.#validate === undefined)
35
+ return true;
36
+ try {
37
+ await this.#validate(image);
38
+ return true;
39
+ }
40
+ catch (error) {
41
+ this.#deps.notice(error instanceof Error ? error.message : String(error));
42
+ return false;
43
+ }
44
+ }
45
+ /** Insert an `[Image #n]` marker at the cursor, padded with spaces. */
46
+ insert(input) {
47
+ const size = input.width === undefined || input.height === undefined
48
+ ? probeImageDimensions(input.data, input.mediaType)
49
+ : undefined;
50
+ const image = {
51
+ ...input,
52
+ ...(input.width === undefined && size !== undefined ? { width: size.width } : {}),
53
+ ...(input.height === undefined && size !== undefined ? { height: size.height } : {}),
54
+ };
55
+ const marker = imageMarker(this.#images.length, image);
56
+ const editor = this.#deps.editor;
57
+ const before = editor.cursor > 0 && !/\s/u.test(editor.text[editor.cursor - 1] ?? '') ? ' ' : '';
58
+ const after = editor.cursor >= editor.text.length || !/\s/u.test(editor.text[editor.cursor] ?? '')
59
+ ? ' '
60
+ : '';
61
+ this.#images.push(image);
62
+ editor.handle({ type: 'text', value: before + marker + after });
63
+ }
64
+ /**
65
+ * Delete the image whose marker touches the cursor, renumbering the rest.
66
+ * Returns true when a draft was removed; the caller repaints.
67
+ */
68
+ removeAtCursor(key) {
69
+ const editor = this.#deps.editor;
70
+ const cursor = editor.cursor;
71
+ for (let index = 0; index < this.#images.length; index += 1) {
72
+ const image = this.#images[index];
73
+ const marker = imageMarker(index, image);
74
+ const start = editor.text.indexOf(marker);
75
+ if (start < 0)
76
+ continue;
77
+ let from = start;
78
+ let to = start + marker.length;
79
+ const touches = key === 'backspace'
80
+ ? cursor > start && cursor <= to
81
+ : cursor >= start && cursor < to;
82
+ if (!touches)
83
+ continue;
84
+ if (editor.text[to] === ' ')
85
+ to += 1;
86
+ else if (from > 0 && editor.text[from - 1] === ' ')
87
+ from -= 1;
88
+ const oldImages = this.#images;
89
+ let text = editor.text.slice(0, from) + editor.text.slice(to);
90
+ const nextImages = oldImages.filter((_, oldIndex) => oldIndex !== index);
91
+ let nextIndex = 0;
92
+ for (let oldIndex = 0; oldIndex < oldImages.length; oldIndex += 1) {
93
+ if (oldIndex === index)
94
+ continue;
95
+ const remaining = oldImages[oldIndex];
96
+ text = text.replaceAll(imageMarker(oldIndex, remaining), imageMarker(nextIndex, remaining));
97
+ nextIndex += 1;
98
+ }
99
+ this.#images = nextImages;
100
+ editor.setText(text, Math.min(from, text.length));
101
+ return true;
102
+ }
103
+ return false;
104
+ }
105
+ /** Drop drafts whose marker left the text, renumbering the survivors. */
106
+ reconcile() {
107
+ if (this.#images.length === 0)
108
+ return;
109
+ const editor = this.#deps.editor;
110
+ const oldImages = this.#images;
111
+ const retained = oldImages.filter((image, index) => editor.text.includes(imageMarker(index, image)));
112
+ if (retained.length === oldImages.length)
113
+ return;
114
+ let text = editor.text;
115
+ let nextIndex = 0;
116
+ for (let oldIndex = 0; oldIndex < oldImages.length; oldIndex += 1) {
117
+ const image = oldImages[oldIndex];
118
+ const oldMarker = imageMarker(oldIndex, image);
119
+ if (!text.includes(oldMarker))
120
+ continue;
121
+ text = text.replaceAll(oldMarker, imageMarker(nextIndex, image));
122
+ nextIndex += 1;
123
+ }
124
+ this.#images = retained;
125
+ editor.setText(text, Math.min(editor.cursor, text.length));
126
+ }
127
+ /** Prepend a queued submission's drafts, rebasing the current markers. */
128
+ restore(submission) {
129
+ const editor = this.#deps.editor;
130
+ const currentImages = this.#images;
131
+ let rebasedCurrent = editor.text;
132
+ for (let index = currentImages.length - 1; index >= 0; index -= 1) {
133
+ const image = currentImages[index];
134
+ rebasedCurrent = rebasedCurrent.replaceAll(imageMarker(index, image), imageMarker(index + submission.images.length, image));
135
+ }
136
+ const separator = submission.text !== '' && rebasedCurrent !== '' ? '\n' : '';
137
+ this.#images = [...submission.images.map(image => ({ ...image })), ...currentImages];
138
+ editor.setText(submission.text + separator + rebasedCurrent);
139
+ }
140
+ /** Replace drafts and text with a queued/edited submission. */
141
+ replace(submission) {
142
+ this.#images = submission.images.map(image => ({ ...image }));
143
+ this.#deps.editor.setText(submission.text);
144
+ }
145
+ clear() {
146
+ this.#images = [];
147
+ }
148
+ }
149
+ //# sourceMappingURL=composer-images.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composer-images.js","sourceRoot":"","sources":["../../src/runtime/composer-images.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Custom Herdr lifecycle integration.
3
+ *
4
+ * Herdr (https://herdr.dev) detects a fixed set of agents and lets every other
5
+ * agent claim a pane's lifecycle authority itself over the local socket
6
+ * (`pane.report_agent` / `pane.release_agent`). This module implements that
7
+ * contract: it reports `idle`, `working`, and `blocked` for omdsh and is a
8
+ * complete no-op outside a Herdr pane.
9
+ *
10
+ * The status projection is a pure controller; the reporter adds the stable
11
+ * source identity, the strictly increasing sequence Herdr requires, the native
12
+ * session reference, and best-effort socket delivery.
13
+ * @module runtime/herdr-agent
14
+ */
15
+ /** Stable, integration-unique source namespace Herdr requires for custom reports. */
16
+ export declare const HERDR_REPORT_SOURCE = "custom:omdsh";
17
+ /** Agent label Herdr shows in its sidebar and agent list. */
18
+ export declare const HERDR_AGENT_LABEL = "omdsh";
19
+ /** The semantic states Herdr accepts from a custom integration; `done` is derived. */
20
+ export type HerdrAgentState = 'idle' | 'working' | 'blocked';
21
+ export interface HerdrAgentStatus {
22
+ readonly state: HerdrAgentState;
23
+ readonly message?: string;
24
+ }
25
+ export interface HerdrRequest {
26
+ readonly id: string;
27
+ readonly method: 'pane.report_agent' | 'pane.release_agent';
28
+ readonly params: Readonly<Record<string, unknown>>;
29
+ }
30
+ /** Delivery seam: production writes one JSON line per request to the local socket. */
31
+ export interface HerdrTransport {
32
+ send(request: HerdrRequest): void;
33
+ }
34
+ export interface HerdrEnvironment {
35
+ readonly paneId: string;
36
+ readonly socketPath: string;
37
+ }
38
+ /**
39
+ * Pane-authoritative Herdr detection.
40
+ *
41
+ * `HERDR_ENV=1` is the canonical marker; the pane id and socket path are what
42
+ * the protocol needs. Client-side overrides (`HERDR_SOCKET_PATH`,
43
+ * `HERDR_BIN_PATH`, `HERDR_SESSION`) can be set outside a pane, so they are
44
+ * never detection evidence on their own.
45
+ */
46
+ export declare function herdrEnvironment(env?: NodeJS.ProcessEnv): HerdrEnvironment | undefined;
47
+ /**
48
+ * Pure state projection: an active driver plus the human prompts it is blocked
49
+ * on decide the single semantic state Herdr understands. `blocked` wins over
50
+ * `working` because a blocked pane must reject `herdr agent prompt` input.
51
+ */
52
+ export declare class HerdrAgentStatusController {
53
+ #private;
54
+ /** The initial report makes Herdr attach the agent to the pane before any turn. */
55
+ start(): HerdrAgentStatus;
56
+ setRunning(running: boolean): HerdrAgentStatus | undefined;
57
+ prompt(message?: string): HerdrAgentStatus | undefined;
58
+ promptResolved(): HerdrAgentStatus | undefined;
59
+ /**
60
+ * Forget the last projection without reporting. A replaced session makes
61
+ * the previous state meaningless, but only a fresh signal may publish,
62
+ * because a compaction or resume can swap sessions mid-driver.
63
+ */
64
+ reset(): void;
65
+ }
66
+ export interface HerdrAgentReporterOptions {
67
+ /** Environment to detect Herdr from. Defaults to `process.env`. */
68
+ readonly env?: NodeJS.ProcessEnv;
69
+ /** Delivery seam for tests. Defaults to the local socket transport. */
70
+ readonly transport?: (socketPath: string) => HerdrTransport;
71
+ /** Clock seam for the monotonic sequence. Defaults to `Date.now`. */
72
+ readonly now?: () => number;
73
+ }
74
+ /**
75
+ * Report omdsh lifecycle state to the Herdr pane that owns this process.
76
+ *
77
+ * Reports are best-effort and silent, matching Herdr's own integrations: a
78
+ * missing or restarted server must never disturb the TUI.
79
+ */
80
+ export declare class HerdrAgentReporter {
81
+ #private;
82
+ constructor(options?: HerdrAgentReporterOptions);
83
+ /** Whether this process runs inside a Herdr pane with a usable socket. */
84
+ get active(): boolean;
85
+ start(): void;
86
+ setRunning(running: boolean): void;
87
+ prompt(message?: string): void;
88
+ promptResolved(): void;
89
+ /** Attach the native session reference Herdr exposes on its agent records. */
90
+ setSession(sessionId: string | undefined): void;
91
+ /** Release the pane's lifecycle authority; later reports are dropped. */
92
+ release(): void;
93
+ }
94
+ /** Herdr exports Unix-style paths; Windows dials them as named pipes. */
95
+ export declare function herdrSocketTarget(socketPath: string, platform?: NodeJS.Platform): string;
@@ -0,0 +1,258 @@
1
+ /**
2
+ * Custom Herdr lifecycle integration.
3
+ *
4
+ * Herdr (https://herdr.dev) detects a fixed set of agents and lets every other
5
+ * agent claim a pane's lifecycle authority itself over the local socket
6
+ * (`pane.report_agent` / `pane.release_agent`). This module implements that
7
+ * contract: it reports `idle`, `working`, and `blocked` for omdsh and is a
8
+ * complete no-op outside a Herdr pane.
9
+ *
10
+ * The status projection is a pure controller; the reporter adds the stable
11
+ * source identity, the strictly increasing sequence Herdr requires, the native
12
+ * session reference, and best-effort socket delivery.
13
+ * @module runtime/herdr-agent
14
+ */
15
+ import { connect } from 'node:net';
16
+ /** Stable, integration-unique source namespace Herdr requires for custom reports. */
17
+ export const HERDR_REPORT_SOURCE = 'custom:omdsh';
18
+ /** Agent label Herdr shows in its sidebar and agent list. */
19
+ export const HERDR_AGENT_LABEL = 'omdsh';
20
+ /**
21
+ * Pane-authoritative Herdr detection.
22
+ *
23
+ * `HERDR_ENV=1` is the canonical marker; the pane id and socket path are what
24
+ * the protocol needs. Client-side overrides (`HERDR_SOCKET_PATH`,
25
+ * `HERDR_BIN_PATH`, `HERDR_SESSION`) can be set outside a pane, so they are
26
+ * never detection evidence on their own.
27
+ */
28
+ export function herdrEnvironment(env = process.env) {
29
+ if (env.HERDR_ENV !== '1')
30
+ return undefined;
31
+ const paneId = env.HERDR_PANE_ID?.trim();
32
+ const socketPath = env.HERDR_SOCKET_PATH?.trim();
33
+ if (paneId === undefined || paneId === '' || socketPath === undefined || socketPath === '')
34
+ return undefined;
35
+ return { paneId, socketPath };
36
+ }
37
+ const HERDR_MESSAGE_LIMIT = 240;
38
+ function cleanHerdrMessage(value) {
39
+ if (value === undefined)
40
+ return undefined;
41
+ const cleaned = value
42
+ .replace(/[\x00-\x1f\x7f-\x9f]/gu, ' ')
43
+ .replace(/\s+/gu, ' ')
44
+ .trim()
45
+ .slice(0, HERDR_MESSAGE_LIMIT);
46
+ return cleaned === '' ? undefined : cleaned;
47
+ }
48
+ /**
49
+ * Pure state projection: an active driver plus the human prompts it is blocked
50
+ * on decide the single semantic state Herdr understands. `blocked` wins over
51
+ * `working` because a blocked pane must reject `herdr agent prompt` input.
52
+ */
53
+ export class HerdrAgentStatusController {
54
+ #running = false;
55
+ #prompts = 0;
56
+ #promptMessage;
57
+ #last;
58
+ /** The initial report makes Herdr attach the agent to the pane before any turn. */
59
+ start() {
60
+ return this.#publish(true);
61
+ }
62
+ setRunning(running) {
63
+ this.#running = running;
64
+ return this.#publish();
65
+ }
66
+ prompt(message) {
67
+ this.#prompts += 1;
68
+ const cleaned = cleanHerdrMessage(message);
69
+ if (cleaned !== undefined)
70
+ this.#promptMessage = cleaned;
71
+ return this.#publish();
72
+ }
73
+ promptResolved() {
74
+ if (this.#prompts === 0)
75
+ return undefined;
76
+ this.#prompts -= 1;
77
+ if (this.#prompts === 0)
78
+ this.#promptMessage = undefined;
79
+ return this.#publish();
80
+ }
81
+ /**
82
+ * Forget the last projection without reporting. A replaced session makes
83
+ * the previous state meaningless, but only a fresh signal may publish,
84
+ * because a compaction or resume can swap sessions mid-driver.
85
+ */
86
+ reset() {
87
+ this.#running = false;
88
+ this.#prompts = 0;
89
+ this.#promptMessage = undefined;
90
+ this.#last = undefined;
91
+ }
92
+ #desired() {
93
+ if (this.#prompts > 0) {
94
+ return this.#promptMessage === undefined
95
+ ? { state: 'blocked' }
96
+ : { state: 'blocked', message: this.#promptMessage };
97
+ }
98
+ return this.#running ? { state: 'working' } : { state: 'idle' };
99
+ }
100
+ #publish(force = false) {
101
+ const next = this.#desired();
102
+ const signature = `${next.state}\u0000${next.message ?? ''}`;
103
+ if (!force && signature === this.#last)
104
+ return undefined;
105
+ this.#last = signature;
106
+ return next;
107
+ }
108
+ }
109
+ /**
110
+ * Report omdsh lifecycle state to the Herdr pane that owns this process.
111
+ *
112
+ * Reports are best-effort and silent, matching Herdr's own integrations: a
113
+ * missing or restarted server must never disturb the TUI.
114
+ */
115
+ export class HerdrAgentReporter {
116
+ #environment;
117
+ #transport;
118
+ #controller = new HerdrAgentStatusController();
119
+ #now;
120
+ #seq;
121
+ #sessionId;
122
+ #released = false;
123
+ constructor(options = {}) {
124
+ this.#now = options.now ?? (() => Date.now());
125
+ this.#seq = this.#now() * 1000;
126
+ this.#environment = herdrEnvironment(options.env ?? process.env);
127
+ this.#transport = this.#environment === undefined
128
+ ? undefined
129
+ : (options.transport ?? defaultHerdrTransport)(this.#environment.socketPath);
130
+ }
131
+ /** Whether this process runs inside a Herdr pane with a usable socket. */
132
+ get active() {
133
+ return this.#transport !== undefined;
134
+ }
135
+ start() {
136
+ this.#report(this.#controller.start());
137
+ }
138
+ setRunning(running) {
139
+ this.#report(this.#controller.setRunning(running));
140
+ }
141
+ prompt(message) {
142
+ this.#report(this.#controller.prompt(message));
143
+ }
144
+ promptResolved() {
145
+ this.#report(this.#controller.promptResolved());
146
+ }
147
+ /** Attach the native session reference Herdr exposes on its agent records. */
148
+ setSession(sessionId) {
149
+ const trimmed = sessionId?.trim();
150
+ const next = trimmed === undefined || trimmed === '' ? undefined : trimmed;
151
+ if (next === this.#sessionId)
152
+ return;
153
+ this.#sessionId = next;
154
+ this.#controller.reset();
155
+ }
156
+ /** Release the pane's lifecycle authority; later reports are dropped. */
157
+ release() {
158
+ const environment = this.#environment;
159
+ const transport = this.#transport;
160
+ if (this.#released || environment === undefined || transport === undefined)
161
+ return;
162
+ this.#released = true;
163
+ this.#deliver(transport, {
164
+ id: `${HERDR_REPORT_SOURCE}:release:${this.#now()}`,
165
+ method: 'pane.release_agent',
166
+ params: {
167
+ pane_id: environment.paneId,
168
+ source: HERDR_REPORT_SOURCE,
169
+ agent: HERDR_AGENT_LABEL,
170
+ seq: this.#nextSeq(),
171
+ },
172
+ });
173
+ }
174
+ #report(status) {
175
+ const environment = this.#environment;
176
+ const transport = this.#transport;
177
+ if (status === undefined || this.#released || environment === undefined || transport === undefined)
178
+ return;
179
+ const params = {
180
+ pane_id: environment.paneId,
181
+ source: HERDR_REPORT_SOURCE,
182
+ agent: HERDR_AGENT_LABEL,
183
+ state: status.state,
184
+ seq: this.#nextSeq(),
185
+ };
186
+ if (status.message !== undefined)
187
+ params.message = status.message;
188
+ if (this.#sessionId !== undefined)
189
+ params.agent_session_id = this.#sessionId;
190
+ this.#deliver(transport, {
191
+ id: `${HERDR_REPORT_SOURCE}:${status.state}:${this.#now()}`,
192
+ method: 'pane.report_agent',
193
+ params,
194
+ });
195
+ }
196
+ /** A broken transport must never throw into the TUI's status or dispose path. */
197
+ #deliver(transport, request) {
198
+ try {
199
+ transport.send(request);
200
+ }
201
+ catch {
202
+ // Best-effort delivery, matching Herdr's own integrations.
203
+ }
204
+ }
205
+ /**
206
+ * Strictly increasing across reporter instances in one process: Herdr
207
+ * ignores a report whose sequence is not above the last accepted one for the
208
+ * same source, so a plugin reload must not restart below a used sequence.
209
+ */
210
+ #nextSeq() {
211
+ this.#seq = Math.max(this.#seq + 1, this.#now() * 1000);
212
+ return this.#seq;
213
+ }
214
+ }
215
+ const HERDR_REQUEST_TIMEOUT_MS = 500;
216
+ /**
217
+ * One JSON line per request over a short-lived local connection. The server
218
+ * acknowledges every request, but delivery stays fire-and-forget: the pane
219
+ * must never wait on Herdr, and `unref()` keeps a pending write from holding
220
+ * the process open.
221
+ */
222
+ function defaultHerdrTransport(socketPath) {
223
+ const target = herdrSocketTarget(socketPath);
224
+ return {
225
+ send(request) {
226
+ let socket;
227
+ try {
228
+ socket = connect(target);
229
+ }
230
+ catch {
231
+ return;
232
+ }
233
+ socket.unref();
234
+ let timer;
235
+ const finish = () => {
236
+ if (timer !== undefined)
237
+ clearTimeout(timer);
238
+ socket.destroy();
239
+ };
240
+ timer = setTimeout(finish, HERDR_REQUEST_TIMEOUT_MS);
241
+ timer.unref();
242
+ socket.on('error', finish);
243
+ socket.on('connect', () => { socket.write(`${JSON.stringify(request)}\n`); });
244
+ socket.on('data', finish);
245
+ socket.on('end', finish);
246
+ socket.on('close', finish);
247
+ },
248
+ };
249
+ }
250
+ /** Herdr exports Unix-style paths; Windows dials them as named pipes. */
251
+ export function herdrSocketTarget(socketPath, platform = process.platform) {
252
+ const lowered = socketPath.toLowerCase();
253
+ if (platform !== 'win32' || lowered.startsWith('\\\\.\\pipe\\') || lowered.startsWith('\\\\?\\pipe\\')) {
254
+ return socketPath;
255
+ }
256
+ return `\\\\.\\pipe\\${socketPath}`;
257
+ }
258
+ //# sourceMappingURL=herdr-agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"herdr-agent.js","sourceRoot":"","sources":["../../src/runtime/herdr-agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /** Non-TTY line input and incremental transcript printing. */
2
+ import type { TuiPrompt, TuiSubmission } from '../definition.ts';
3
+ import type { Block } from '../views/event-views.ts';
4
+ import type { TerminalLike } from './provider-local.ts';
5
+ export type PendingRead = {
6
+ resolve: (submission: TuiSubmission | null) => void;
7
+ signal?: AbortSignal | null;
8
+ /** Detaches this read's abort listener once the read settles. */
9
+ offAbort?: () => void;
10
+ };
11
+ export interface PlainTuiDeps {
12
+ readonly term: TerminalLike;
13
+ /** Transcript blocks, read live so `print()` always flushes the newest tail. */
14
+ blocks(): readonly Block[];
15
+ /** The in-flight human prompt's request, if one is waiting on an answer. */
16
+ promptRequest(): TuiPrompt | undefined;
17
+ /** Resolve the in-flight prompt; the provider owns prompt bookkeeping. */
18
+ finishPrompt(answer: string | null): void;
19
+ }
20
+ /**
21
+ * Pipe-mode counterpart of the TTY reader: a readline queue that buffers lines
22
+ * until the runner asks for the next submission, plus incremental transcript
23
+ * printing that emits each settled block exactly once.
24
+ */
25
+ export declare class PlainTui {
26
+ #private;
27
+ constructor(deps: PlainTuiDeps);
28
+ readline(signal?: AbortSignal): Promise<TuiSubmission | null>;
29
+ /** Print blocks that settled since the last flush. */
30
+ print(): void;
31
+ /** Forget the print cursor so a replaced transcript reprints in full. */
32
+ resetPrinted(): void;
33
+ dispose(): void;
34
+ }