@hwip/cli 0.0.1 → 0.1.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.
- package/LICENSE +190 -0
- package/NOTICE +11 -0
- package/README.md +1979 -0
- package/dist/agent-list.d.ts +76 -0
- package/dist/agent-list.js +102 -0
- package/dist/agent-read.d.ts +105 -0
- package/dist/agent-read.js +309 -0
- package/dist/agent-rules-fetch.d.ts +51 -0
- package/dist/agent-rules-fetch.js +275 -0
- package/dist/agent-rules.default.d.ts +30 -0
- package/dist/agent-rules.default.js +292 -0
- package/dist/agent-session.d.ts +23 -0
- package/dist/agent-session.js +44 -0
- package/dist/agent-state.d.ts +84 -0
- package/dist/agent-state.js +188 -0
- package/dist/agent-target.d.ts +60 -0
- package/dist/agent-target.js +81 -0
- package/dist/agents.d.ts +31 -0
- package/dist/agents.js +75 -0
- package/dist/api.d.ts +28 -0
- package/dist/api.js +76 -0
- package/dist/args.d.ts +74 -0
- package/dist/args.js +254 -0
- package/dist/ask-context-attach.d.ts +73 -0
- package/dist/ask-context-attach.js +151 -0
- package/dist/ask-context-screen.d.ts +21 -0
- package/dist/ask-context-screen.js +49 -0
- package/dist/ask-context-switch.d.ts +31 -0
- package/dist/ask-context-switch.js +74 -0
- package/dist/ask-context.d.ts +84 -0
- package/dist/ask-context.js +172 -0
- package/dist/ask-pending.d.ts +47 -0
- package/dist/ask-pending.js +221 -0
- package/dist/ask-seal.d.ts +120 -0
- package/dist/ask-seal.js +179 -0
- package/dist/ask.d.ts +107 -0
- package/dist/ask.js +551 -0
- package/dist/blocked-prompt-seal.d.ts +35 -0
- package/dist/blocked-prompt-seal.js +89 -0
- package/dist/blocked-prompt.d.ts +57 -0
- package/dist/blocked-prompt.js +181 -0
- package/dist/channel.d.ts +67 -0
- package/dist/channel.js +136 -0
- package/dist/check-update.d.ts +28 -0
- package/dist/check-update.js +153 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +813 -0
- package/dist/codex-config.d.ts +24 -0
- package/dist/codex-config.js +169 -0
- package/dist/codex-transcript.d.ts +59 -0
- package/dist/codex-transcript.js +373 -0
- package/dist/command-refusal.d.ts +56 -0
- package/dist/command-refusal.js +127 -0
- package/dist/command-scan.d.ts +46 -0
- package/dist/command-scan.js +154 -0
- package/dist/command-seal.d.ts +57 -0
- package/dist/command-seal.js +88 -0
- package/dist/command-seq.d.ts +30 -0
- package/dist/command-seq.js +150 -0
- package/dist/config.d.ts +156 -0
- package/dist/config.js +392 -0
- package/dist/core-sections.d.ts +18 -0
- package/dist/core-sections.js +28 -0
- package/dist/crypto.d.ts +278 -0
- package/dist/crypto.js +698 -0
- package/dist/desktop-notify.d.ts +33 -0
- package/dist/desktop-notify.js +49 -0
- package/dist/device-directory.d.ts +36 -0
- package/dist/device-directory.js +97 -0
- package/dist/device-presence.d.ts +17 -0
- package/dist/device-presence.js +62 -0
- package/dist/downloads.d.ts +29 -0
- package/dist/downloads.js +106 -0
- package/dist/errors.d.ts +12 -0
- package/dist/errors.js +28 -0
- package/dist/file-crypto.d.ts +94 -0
- package/dist/file-crypto.js +272 -0
- package/dist/file-view-budget.d.ts +15 -0
- package/dist/file-view-budget.js +34 -0
- package/dist/file-view-switch.d.ts +28 -0
- package/dist/file-view-switch.js +122 -0
- package/dist/file-view.d.ts +108 -0
- package/dist/file-view.js +327 -0
- package/dist/gate.d.ts +141 -0
- package/dist/gate.js +336 -0
- package/dist/gemini-transcript.d.ts +32 -0
- package/dist/gemini-transcript.js +189 -0
- package/dist/http-failure.d.ts +98 -0
- package/dist/http-failure.js +349 -0
- package/dist/hwip-core.generated.d.ts +7 -0
- package/dist/hwip-core.generated.js +14 -0
- package/dist/hwip-hook.d.ts +77 -0
- package/dist/hwip-hook.js +340 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +14 -0
- package/dist/input-sequencer.d.ts +65 -0
- package/dist/input-sequencer.js +142 -0
- package/dist/insecure-url.d.ts +16 -0
- package/dist/insecure-url.js +76 -0
- package/dist/installer.d.ts +96 -0
- package/dist/installer.js +850 -0
- package/dist/inventory-offload.d.ts +49 -0
- package/dist/inventory-offload.js +209 -0
- package/dist/inventory-worker.d.ts +2 -0
- package/dist/inventory-worker.js +27 -0
- package/dist/jsonc-doc.d.ts +106 -0
- package/dist/jsonc-doc.js +354 -0
- package/dist/keep-awake.d.ts +32 -0
- package/dist/keep-awake.js +46 -0
- package/dist/key-changes.d.ts +48 -0
- package/dist/key-changes.js +140 -0
- package/dist/lan-auth.d.ts +140 -0
- package/dist/lan-auth.js +217 -0
- package/dist/lan-endpoint.d.ts +41 -0
- package/dist/lan-endpoint.js +115 -0
- package/dist/lan-receiver.d.ts +122 -0
- package/dist/lan-receiver.js +510 -0
- package/dist/lan-sender.d.ts +76 -0
- package/dist/lan-sender.js +184 -0
- package/dist/lan-transfer.d.ts +36 -0
- package/dist/lan-transfer.js +54 -0
- package/dist/listener-device-id.d.ts +20 -0
- package/dist/listener-device-id.js +133 -0
- package/dist/listener-log.d.ts +4 -0
- package/dist/listener-log.js +23 -0
- package/dist/listener-process.d.ts +200 -0
- package/dist/listener-process.js +470 -0
- package/dist/listener-service.d.ts +225 -0
- package/dist/listener-service.js +682 -0
- package/dist/listener-worktree-cleanup.d.ts +27 -0
- package/dist/listener-worktree-cleanup.js +62 -0
- package/dist/listener.d.ts +1325 -0
- package/dist/listener.js +5680 -0
- package/dist/login-address.d.ts +25 -0
- package/dist/login-address.js +97 -0
- package/dist/login-page.d.ts +29 -0
- package/dist/login-page.js +93 -0
- package/dist/login.d.ts +98 -0
- package/dist/login.js +388 -0
- package/dist/mcp-command.d.ts +45 -0
- package/dist/mcp-command.js +50 -0
- package/dist/mcp.d.ts +19 -0
- package/dist/mcp.js +29 -0
- package/dist/node-support.d.ts +19 -0
- package/dist/node-support.js +38 -0
- package/dist/notify-failure.d.ts +57 -0
- package/dist/notify-failure.js +150 -0
- package/dist/opencode-transcript.d.ts +139 -0
- package/dist/opencode-transcript.js +390 -0
- package/dist/optional-features.d.ts +6 -0
- package/dist/optional-features.js +19 -0
- package/dist/pane-fit.d.ts +40 -0
- package/dist/pane-fit.js +119 -0
- package/dist/peer-key.d.ts +33 -0
- package/dist/peer-key.js +34 -0
- package/dist/pi-transcript.d.ts +26 -0
- package/dist/pi-transcript.js +255 -0
- package/dist/presence.d.ts +14 -0
- package/dist/presence.js +124 -0
- package/dist/private-files.d.ts +51 -0
- package/dist/private-files.js +218 -0
- package/dist/project-switch.d.ts +19 -0
- package/dist/project-switch.js +60 -0
- package/dist/redact.d.ts +10 -0
- package/dist/redact.js +21 -0
- package/dist/remote-agents.d.ts +410 -0
- package/dist/remote-agents.js +1218 -0
- package/dist/remote-hook.d.ts +12 -0
- package/dist/remote-hook.js +196 -0
- package/dist/replace-file.d.ts +50 -0
- package/dist/replace-file.js +328 -0
- package/dist/schedule-command.d.ts +35 -0
- package/dist/schedule-command.js +260 -0
- package/dist/schedule-launch.d.ts +15 -0
- package/dist/schedule-launch.js +24 -0
- package/dist/schedule-ready.d.ts +44 -0
- package/dist/schedule-ready.js +71 -0
- package/dist/schedule-remote.d.ts +77 -0
- package/dist/schedule-remote.js +167 -0
- package/dist/schedule-runner.d.ts +89 -0
- package/dist/schedule-runner.js +452 -0
- package/dist/schedule.d.ts +149 -0
- package/dist/schedule.js +428 -0
- package/dist/secret-mask.d.ts +29 -0
- package/dist/secret-mask.js +245 -0
- package/dist/self-register.d.ts +45 -0
- package/dist/self-register.js +67 -0
- package/dist/send.d.ts +56 -0
- package/dist/send.js +104 -0
- package/dist/session-diff.d.ts +161 -0
- package/dist/session-diff.js +445 -0
- package/dist/session-registry.d.ts +143 -0
- package/dist/session-registry.js +216 -0
- package/dist/sessions-report.d.ts +59 -0
- package/dist/sessions-report.js +99 -0
- package/dist/shell-audit.d.ts +34 -0
- package/dist/shell-audit.js +47 -0
- package/dist/subagent-transcripts.d.ts +167 -0
- package/dist/subagent-transcripts.js +437 -0
- package/dist/subscriber-trust.d.ts +128 -0
- package/dist/subscriber-trust.js +397 -0
- package/dist/templates.d.ts +105 -0
- package/dist/templates.js +871 -0
- package/dist/tmux-install.d.ts +44 -0
- package/dist/tmux-install.js +65 -0
- package/dist/tmux-liveness.d.ts +45 -0
- package/dist/tmux-liveness.js +71 -0
- package/dist/tmux-pane.d.ts +55 -0
- package/dist/tmux-pane.js +126 -0
- package/dist/tmux-socket.d.ts +20 -0
- package/dist/tmux-socket.js +292 -0
- package/dist/todo-fold.d.ts +31 -0
- package/dist/todo-fold.js +102 -0
- package/dist/transcript-tail.d.ts +312 -0
- package/dist/transcript-tail.js +718 -0
- package/dist/trust-command.d.ts +49 -0
- package/dist/trust-command.js +200 -0
- package/dist/trust-lock.d.ts +26 -0
- package/dist/trust-lock.js +94 -0
- package/dist/trust-pins.d.ts +37 -0
- package/dist/trust-pins.js +82 -0
- package/dist/turn-recorder-wire.d.ts +70 -0
- package/dist/turn-recorder-wire.js +165 -0
- package/dist/turn-recorder.d.ts +190 -0
- package/dist/turn-recorder.js +695 -0
- package/dist/turn-ring.d.ts +93 -0
- package/dist/turn-ring.js +418 -0
- package/dist/turn-watch.d.ts +177 -0
- package/dist/turn-watch.js +630 -0
- package/dist/types.d.ts +63 -0
- package/dist/types.js +2 -0
- package/dist/uninstall.d.ts +55 -0
- package/dist/uninstall.js +507 -0
- package/dist/usage.d.ts +17 -0
- package/dist/usage.js +421 -0
- package/dist/verify.d.ts +47 -0
- package/dist/verify.js +396 -0
- package/dist/worktree.d.ts +144 -0
- package/dist/worktree.js +310 -0
- package/dist/wrapper.d.ts +254 -0
- package/dist/wrapper.js +704 -0
- package/dist/ws-url.d.ts +109 -0
- package/dist/ws-url.js +202 -0
- package/package.json +78 -10
- package/bin/hwip.js +0 -3
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code session transcript (`~/.claude/projects/<hash>/<uuid>.jsonl`) →
|
|
3
|
+
* the small events the agent chat timeline draws.
|
|
4
|
+
*
|
|
5
|
+
* Two pure pieces, deliberately split: reading bytes off a growing file, and
|
|
6
|
+
* deciding what of it is worth putting on the wire. Neither touches the socket,
|
|
7
|
+
* so both are testable without tmux, WebSocket, or a clock.
|
|
8
|
+
*
|
|
9
|
+
* Everything here is sized by what a real transcript actually contains, measured
|
|
10
|
+
* 2026-09-08 over 1443 files in `~/.claude/projects`: the largest file was
|
|
11
|
+
* 75.9 MB (p90 1.1 MB) and the longest single line 915,292 bytes. Those two
|
|
12
|
+
* numbers are why the reader starts near the end and refuses oversized lines
|
|
13
|
+
* before parsing them — a tail that starts at byte 0, or that hands a ~1 MB
|
|
14
|
+
* string to `JSON.parse` and only then decides to drop it, has already paid the
|
|
15
|
+
* cost the cap exists to avoid.
|
|
16
|
+
*/
|
|
17
|
+
import { type TodoItem, type TodoList } from './todo-fold.js';
|
|
18
|
+
/**
|
|
19
|
+
* How far back from the end of the file the first read starts.
|
|
20
|
+
*
|
|
21
|
+
* Not zero: a fresh viewer that sees nothing until the *next* tool call is a
|
|
22
|
+
* blank screen for whoever just picked up their phone mid-turn. Not the whole
|
|
23
|
+
* file either — that is up to 75.9 MB. A fixed window from the end costs the
|
|
24
|
+
* same on an 8 KB transcript and a 76 MB one.
|
|
25
|
+
*/
|
|
26
|
+
export declare const TRANSCRIPT_BACKFILL_BYTES: number;
|
|
27
|
+
/** Ceiling on one tick's read, so a burst of appends cannot be swallowed whole. */
|
|
28
|
+
export declare const MAX_TAIL_BYTES_PER_TICK: number;
|
|
29
|
+
/**
|
|
30
|
+
* A line longer than this is abandoned unparsed, the reader skipping to the next
|
|
31
|
+
* newline. The measured worst case is a 915 KB `tool_result`, whose body this
|
|
32
|
+
* module drops anyway — buffering one to completion would be paying megabytes to
|
|
33
|
+
* learn a tool id.
|
|
34
|
+
*/
|
|
35
|
+
export declare const MAX_TRANSCRIPT_LINE_CHARS: number;
|
|
36
|
+
/**
|
|
37
|
+
* Ceiling on a tool's label — its name, and the short string saying what it
|
|
38
|
+
* acted on. A path or a one-line description; anything longer is a runaway
|
|
39
|
+
* input, not a label.
|
|
40
|
+
*/
|
|
41
|
+
export declare const MAX_EVENT_FIELD_CHARS = 512;
|
|
42
|
+
/**
|
|
43
|
+
* Ceiling on prose — what the agent wrote, and what the person asked.
|
|
44
|
+
*
|
|
45
|
+
* Deliberately far above the label cap: 512 characters is a filename, and
|
|
46
|
+
* applying it here cut every reply off mid-sentence. 5000 is what the
|
|
47
|
+
* completion push already carries for the same text (`hwip-stop.sh`), so the
|
|
48
|
+
* live lane and the push that replaces it agree on how much of a reply is
|
|
49
|
+
* worth sending.
|
|
50
|
+
*/
|
|
51
|
+
export declare const MAX_EVENT_TEXT_CHARS = 5000;
|
|
52
|
+
/**
|
|
53
|
+
* Where the reader is in one file.
|
|
54
|
+
*
|
|
55
|
+
* `size`/`mtimeMs` are the skip check: when neither moved there is nothing to
|
|
56
|
+
* read, and the tick returns without allocating. Since idle is this watcher's
|
|
57
|
+
* normal state, that check is what keeps it off the GC's back.
|
|
58
|
+
*/
|
|
59
|
+
export interface TailState {
|
|
60
|
+
readonly offset: number;
|
|
61
|
+
readonly size: number;
|
|
62
|
+
readonly mtimeMs: number;
|
|
63
|
+
/** Which file this offset belongs to. A new inode is a new file at the same path. */
|
|
64
|
+
readonly ino: number;
|
|
65
|
+
/** Bytes after the last newline seen — an incomplete line, held for the next tick. */
|
|
66
|
+
readonly carry: string;
|
|
67
|
+
/**
|
|
68
|
+
* How many bytes of the FILE `carry` stands for. Not `Buffer.byteLength(carry)`: a
|
|
69
|
+
* byte that is not valid UTF-8 decodes to U+FFFD, three bytes when written back, so
|
|
70
|
+
* the length of the string says nothing about the offset the line began at.
|
|
71
|
+
*/
|
|
72
|
+
readonly carryBytes?: number;
|
|
73
|
+
/** Inside an oversized line: discard bytes until the next newline. */
|
|
74
|
+
readonly resyncing: boolean;
|
|
75
|
+
/** While `resyncing`: the offset where the oversized line began — the last place a restart can safely resume. */
|
|
76
|
+
readonly resyncFrom?: number;
|
|
77
|
+
/** tool_result ids read off the head of the oversized line being skipped, reported when it ends. */
|
|
78
|
+
readonly salvage: readonly string[];
|
|
79
|
+
/**
|
|
80
|
+
* Where a `TranscriptReader` that is not reading a file is, in its own
|
|
81
|
+
* terms (opencode's: a row position in its database). Opaque to everything
|
|
82
|
+
* but the reader that wrote it; the file tailer never sets it.
|
|
83
|
+
*/
|
|
84
|
+
readonly cursor?: unknown;
|
|
85
|
+
}
|
|
86
|
+
export interface TailRead {
|
|
87
|
+
/** Whole lines, in file order. Never includes a partial line. */
|
|
88
|
+
readonly lines: string[];
|
|
89
|
+
readonly state: TailState;
|
|
90
|
+
readonly bytesRead: number;
|
|
91
|
+
/** Lines abandoned for exceeding MAX_TRANSCRIPT_LINE_CHARS. */
|
|
92
|
+
readonly droppedLines: number;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* No state yet. `null` rather than a sentinel-filled record: "never read this
|
|
96
|
+
* file" and "read it and got nothing" are different, and an out-of-band value
|
|
97
|
+
* that has to stay below every real offset is a trap for the next `>=`.
|
|
98
|
+
*/
|
|
99
|
+
export declare const initialTailState: () => TailState | null;
|
|
100
|
+
/**
|
|
101
|
+
* Read what was appended since `prev`, or `null` when there is nothing to do —
|
|
102
|
+
* the file is unreadable, or neither its size nor its mtime moved.
|
|
103
|
+
*
|
|
104
|
+
* `null` is the common case (an idle session) and is deliberately allocation
|
|
105
|
+
* free: no buffer, no string, no array.
|
|
106
|
+
*/
|
|
107
|
+
export declare const readTranscriptDelta: (path: string, prev: TailState | null, opts?: {
|
|
108
|
+
fromStart?: boolean;
|
|
109
|
+
}) => TailRead | null;
|
|
110
|
+
/**
|
|
111
|
+
* What the timeline draws. Stateless by design: a `tool_result` arrives as its
|
|
112
|
+
* own event rather than mutating an earlier one, because the call it answers is
|
|
113
|
+
* routinely in a previous tick's batch — merging by `id` is the viewer's job,
|
|
114
|
+
* and it is the only side that holds the whole turn.
|
|
115
|
+
*/
|
|
116
|
+
/**
|
|
117
|
+
* `at` is the transcript entry's own timestamp, carried so the viewer can place
|
|
118
|
+
* a live turn among the pushes in time order instead of parking the whole live
|
|
119
|
+
* block below them — where a message sent while reading lands above the turn it
|
|
120
|
+
* answers.
|
|
121
|
+
*/
|
|
122
|
+
export type TurnEvent = {
|
|
123
|
+
at?: string;
|
|
124
|
+
} & ({
|
|
125
|
+
kind: 'tool';
|
|
126
|
+
id: string;
|
|
127
|
+
name: string;
|
|
128
|
+
target?: string;
|
|
129
|
+
add?: number;
|
|
130
|
+
del?: number;
|
|
131
|
+
} | {
|
|
132
|
+
kind: 'tool_result';
|
|
133
|
+
id: string;
|
|
134
|
+
ok: boolean;
|
|
135
|
+
lines?: number;
|
|
136
|
+
} | {
|
|
137
|
+
kind: 'text';
|
|
138
|
+
text: string;
|
|
139
|
+
} | {
|
|
140
|
+
kind: 'prompt';
|
|
141
|
+
text: string;
|
|
142
|
+
} | {
|
|
143
|
+
kind: 'msg';
|
|
144
|
+
mid: string;
|
|
145
|
+
model?: string;
|
|
146
|
+
out: number;
|
|
147
|
+
ctx: number;
|
|
148
|
+
thinking?: number;
|
|
149
|
+
} | {
|
|
150
|
+
kind: 'todo';
|
|
151
|
+
items: TodoItem[];
|
|
152
|
+
total?: number;
|
|
153
|
+
done?: number;
|
|
154
|
+
});
|
|
155
|
+
/**
|
|
156
|
+
* What a projector is told about the read it is projecting.
|
|
157
|
+
*
|
|
158
|
+
* Both flags are about the *read*, not about any one format, but only
|
|
159
|
+
* `sinceLastPrompt` means something to every agent: it is "this is a backfill,
|
|
160
|
+
* keep the turn still in flight". `includeSidechain` is Claude Code's word for
|
|
161
|
+
* its in-process subagents, and an agent with no such concept ignores it. A
|
|
162
|
+
* projector ignoring an option its format has no notion of is the contract, not
|
|
163
|
+
* an oversight — do not read an unused field here as a missed case.
|
|
164
|
+
*/
|
|
165
|
+
export interface ProjectorOptions {
|
|
166
|
+
sinceLastPrompt?: boolean;
|
|
167
|
+
includeSidechain?: boolean;
|
|
168
|
+
/**
|
|
169
|
+
* Told the name of each entry the projector skipped because it does not
|
|
170
|
+
* know the shape — a vendor format change otherwise thins the timeline
|
|
171
|
+
* without a word (C70). Called per skipped entry; the caller dedupes.
|
|
172
|
+
*/
|
|
173
|
+
onUnknown?: (what: string) => void;
|
|
174
|
+
/**
|
|
175
|
+
* The to-do list as it stood before these lines. A projector that folds a
|
|
176
|
+
* list (Claude Code's task tools) starts from it and emits a `todo` event
|
|
177
|
+
* only when the list changed. The caller holds it between reads, because a
|
|
178
|
+
* projector holds nothing.
|
|
179
|
+
*/
|
|
180
|
+
todo?: TodoList;
|
|
181
|
+
/**
|
|
182
|
+
* Told the list, whole and uncut, when these lines changed it — what the
|
|
183
|
+
* caller passes back as `todo` next time. The event itself is cut to the
|
|
184
|
+
* wire's budget and so cannot stand in for it.
|
|
185
|
+
*/
|
|
186
|
+
onTodo?: (list: TodoList) => void;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* One agent's transcript format, reduced to the events the timeline draws.
|
|
190
|
+
*
|
|
191
|
+
* Pure by contract: lines in, events out, no filesystem and no clock. That is
|
|
192
|
+
* what lets `readTranscriptDelta` above stay the single tailer for every agent
|
|
193
|
+
* whose transcript is an append-only text log — the bytes are the same problem
|
|
194
|
+
* for all of them, and only the shape of a line differs.
|
|
195
|
+
*/
|
|
196
|
+
export type TranscriptProjector = (lines: readonly string[], opts?: ProjectorOptions) => TurnEvent[];
|
|
197
|
+
/**
|
|
198
|
+
* A transcript and the projector that can read it, resolved together.
|
|
199
|
+
*
|
|
200
|
+
* They travel as one because they are one answer: a path with no projector is a
|
|
201
|
+
* file nothing can parse, which reaches a viewer as an empty timeline — strictly
|
|
202
|
+
* worse than the honest `no_transcript` it would replace. Resolving them apart
|
|
203
|
+
* would also mean two `detectRemoteAgent` lookups per recheck, on a path that is
|
|
204
|
+
* uncached and blocking (see `TurnWatchDeps.resolveTranscript`).
|
|
205
|
+
*/
|
|
206
|
+
export interface TranscriptSource {
|
|
207
|
+
readonly path: string;
|
|
208
|
+
readonly project: TranscriptProjector;
|
|
209
|
+
/**
|
|
210
|
+
* How to read `path`, when it is not an append-only file. Absent for every
|
|
211
|
+
* agent that writes one — `readTranscriptDelta` reads those. opencode keeps
|
|
212
|
+
* its sessions in SQLite, so its row carries a reader of its own and its
|
|
213
|
+
* `path` names a session in the database rather than a file.
|
|
214
|
+
*/
|
|
215
|
+
readonly read?: TranscriptReader;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* What was added to a transcript since `prev`, or null when nothing was —
|
|
219
|
+
* `readTranscriptDelta`'s contract, for a transcript that is not a file.
|
|
220
|
+
*/
|
|
221
|
+
export type TranscriptReader = (path: string, prev: TailState | null) => TailRead | null;
|
|
222
|
+
/** One read of a source, through its own reader when it has one. */
|
|
223
|
+
export declare const readSource: (source: TranscriptSource, prev: TailState | null) => TailRead | null;
|
|
224
|
+
/** Edits larger than this are counted, not diffed: splitting them into lines
|
|
225
|
+
* is the one allocation here that scales with what the agent wrote. */
|
|
226
|
+
export declare const EDIT_DIFF_MAX_CHARS: number;
|
|
227
|
+
/** Lines of a result's text — a string, or the text blocks of a block list. Images and the like count as nothing. */
|
|
228
|
+
/**
|
|
229
|
+
* How long a tool result was, from either shape a result body takes: a bare
|
|
230
|
+
* string, or blocks with a `text` field. Exported for the same reason as
|
|
231
|
+
* `clamp` — the shape is not one agent's vocabulary, and `lines` means the same
|
|
232
|
+
* number on the wire whoever produced it.
|
|
233
|
+
*/
|
|
234
|
+
export declare const resultLinesOf: (content: unknown) => number;
|
|
235
|
+
/**
|
|
236
|
+
* One line, always.
|
|
237
|
+
*
|
|
238
|
+
* A label is not a paragraph: a tool argument that runs to hundreds of
|
|
239
|
+
* characters with newlines in it renders as a wall where a row's label belongs.
|
|
240
|
+
* Applied by the projectors that need it rather than inside `targetFrom`,
|
|
241
|
+
* because that helper feeds Claude's projector too and the Spec requires a
|
|
242
|
+
* Claude timeline to stay byte-identical.
|
|
243
|
+
*/
|
|
244
|
+
export declare const oneLine: (target: string | undefined) => string | undefined;
|
|
245
|
+
/**
|
|
246
|
+
* The backfill window, applied the same way by every projector.
|
|
247
|
+
*
|
|
248
|
+
* This is about `TurnEvent` and `ProjectorOptions`, not about any one agent's
|
|
249
|
+
* vocabulary — unlike the per-format helpers beside it, which are deliberately
|
|
250
|
+
* not shared. Every projector ends with this call, and a fourth one should too.
|
|
251
|
+
*/
|
|
252
|
+
export declare const sliceSinceLastPrompt: (events: TurnEvent[], opts: ProjectorOptions) => TurnEvent[];
|
|
253
|
+
/**
|
|
254
|
+
* Ceilings on a `todo` event: tasks kept, and characters per task. 30 tasks of
|
|
255
|
+
* 100 Hangul characters each is under 10KB of JSON, inside the 12KB frame
|
|
256
|
+
* (`MAX_TURN_FRAME_BYTES` in `turn-watch`), which sends an oversized event whole
|
|
257
|
+
* rather than cutting it.
|
|
258
|
+
*/
|
|
259
|
+
export declare const MAX_TODO_ITEMS = 30;
|
|
260
|
+
export declare const MAX_TODO_TEXT_CHARS = 100;
|
|
261
|
+
/**
|
|
262
|
+
* The `todo` event for a list. Over `MAX_TODO_ITEMS`, finished tasks go first,
|
|
263
|
+
* oldest first — what is left to do is what the phone is watching for — and
|
|
264
|
+
* `total` · `done` keep the real counts.
|
|
265
|
+
*/
|
|
266
|
+
export declare const todoEventOf: (list: TodoList, at: string | undefined) => Extract<TurnEvent, {
|
|
267
|
+
kind: "todo";
|
|
268
|
+
}>;
|
|
269
|
+
/** A usable number, or 0 — token counts are the one place a missing field must not become `NaN` on the wire. */
|
|
270
|
+
export declare const finiteNumber: (value: unknown) => number;
|
|
271
|
+
/**
|
|
272
|
+
* Cut one field to the wire's budget. Exported because every projector shares
|
|
273
|
+
* the same 12KB frame ceiling (`MAX_TURN_FRAME_BYTES` in `turn-watch`), so a
|
|
274
|
+
* second projector with its own idea of "long enough" would be a second way to
|
|
275
|
+
* overflow the one transport.
|
|
276
|
+
*/
|
|
277
|
+
export declare const clamp: (value: string, max?: number) => string;
|
|
278
|
+
/**
|
|
279
|
+
* First of `keys` that holds a non-blank string, clamped — the loop every
|
|
280
|
+
* projector needs, without the key list every projector has to choose for
|
|
281
|
+
* itself. The keys stay the caller's: they are that agent's vocabulary, and
|
|
282
|
+
* merging them into one list is exactly what the `TARGET_KEYS` note forbids.
|
|
283
|
+
*/
|
|
284
|
+
export declare const targetFrom: (input: unknown, keys: readonly string[]) => string | undefined;
|
|
285
|
+
/**
|
|
286
|
+
* Turn raw JSONL lines into wire events.
|
|
287
|
+
*
|
|
288
|
+
* Nothing a tool read or wrote survives this function: only the tool's name, a
|
|
289
|
+
* short label for what it acted on, whether it worked, and numbers about it —
|
|
290
|
+
* lines changed, result length, a message's tokens and model. That is the whole
|
|
291
|
+
* privacy story of the feature — the transcript holds file contents and command
|
|
292
|
+
* output, and this is the one place that decides none of it leaves the machine.
|
|
293
|
+
*
|
|
294
|
+
* `sinceLastPrompt` is for the backfill window: finished turns already exist in
|
|
295
|
+
* the chat as their completion pushes, so replaying them would double every
|
|
296
|
+
* message. Only the turn still in flight is new information.
|
|
297
|
+
*
|
|
298
|
+
* The prompt a person typed IS carried, unlike anything a tool read or wrote.
|
|
299
|
+
* It is their own words, it is the same class of content the completion push
|
|
300
|
+
* already sends, and without it the timeline is a list of tool names with no
|
|
301
|
+
* record of what was asked.
|
|
302
|
+
*
|
|
303
|
+
* Everything here — the block shapes, the entry types, `TARGET_KEYS` — is Claude
|
|
304
|
+
* Code's transcript format. Supporting another agent (pi, Codex) means a
|
|
305
|
+
* projector of its own alongside this one, satisfying `TranscriptProjector` and
|
|
306
|
+
* reached the way `REMOTE_AGENTS` already reaches per-agent session resolvers:
|
|
307
|
+
* `RemoteAgent.projectTranscript`, resolved together with the path as a
|
|
308
|
+
* `TranscriptSource`. `turn-watch` calls whichever projector it is handed and
|
|
309
|
+
* knows about none of them by name.
|
|
310
|
+
*/
|
|
311
|
+
export declare const projectTranscriptEntries: TranscriptProjector;
|
|
312
|
+
//# sourceMappingURL=transcript-tail.d.ts.map
|