@cluesmith/codev 3.3.3 → 3.3.5
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/dashboard-dist/assets/index-BuflRUi6.js +220 -0
- package/dashboard-dist/assets/index-BuflRUi6.js.map +1 -0
- package/dashboard-dist/assets/index-r3bZzLmX.css +32 -0
- package/dashboard-dist/index.html +2 -2
- package/dist/agent-farm/cli.d.ts.map +1 -1
- package/dist/agent-farm/cli.js +48 -0
- package/dist/agent-farm/cli.js.map +1 -1
- package/dist/agent-farm/commands/ide.d.ts +20 -0
- package/dist/agent-farm/commands/ide.d.ts.map +1 -0
- package/dist/agent-farm/commands/ide.js +138 -0
- package/dist/agent-farm/commands/ide.js.map +1 -0
- package/dist/agent-farm/commands/inbox.d.ts.map +1 -1
- package/dist/agent-farm/commands/inbox.js +15 -3
- package/dist/agent-farm/commands/inbox.js.map +1 -1
- package/dist/agent-farm/commands/send.d.ts +3 -2
- package/dist/agent-farm/commands/send.d.ts.map +1 -1
- package/dist/agent-farm/commands/send.js +40 -6
- package/dist/agent-farm/commands/send.js.map +1 -1
- package/dist/agent-farm/commands/spawn-worktree.d.ts.map +1 -1
- package/dist/agent-farm/commands/spawn-worktree.js +28 -9
- package/dist/agent-farm/commands/spawn-worktree.js.map +1 -1
- package/dist/agent-farm/commands/tower.d.ts +21 -9
- package/dist/agent-farm/commands/tower.d.ts.map +1 -1
- package/dist/agent-farm/commands/tower.js +90 -30
- package/dist/agent-farm/commands/tower.js.map +1 -1
- package/dist/agent-farm/db/tower-owner.d.ts +168 -0
- package/dist/agent-farm/db/tower-owner.d.ts.map +1 -0
- package/dist/agent-farm/db/tower-owner.js +369 -0
- package/dist/agent-farm/db/tower-owner.js.map +1 -0
- package/dist/agent-farm/db/types.d.ts +30 -5
- package/dist/agent-farm/db/types.d.ts.map +1 -1
- package/dist/agent-farm/db/types.js.map +1 -1
- package/dist/agent-farm/lib/ide-record.d.ts +65 -0
- package/dist/agent-farm/lib/ide-record.d.ts.map +1 -0
- package/dist/agent-farm/lib/ide-record.js +118 -0
- package/dist/agent-farm/lib/ide-record.js.map +1 -0
- package/dist/agent-farm/lib/tunnel-client.d.ts +22 -0
- package/dist/agent-farm/lib/tunnel-client.d.ts.map +1 -1
- package/dist/agent-farm/lib/tunnel-client.js +53 -5
- package/dist/agent-farm/lib/tunnel-client.js.map +1 -1
- package/dist/agent-farm/servers/decisions/file.d.ts +50 -0
- package/dist/agent-farm/servers/decisions/file.d.ts.map +1 -0
- package/dist/agent-farm/servers/decisions/file.js +146 -0
- package/dist/agent-farm/servers/decisions/file.js.map +1 -0
- package/dist/agent-farm/servers/decisions/grammar.d.ts +36 -0
- package/dist/agent-farm/servers/decisions/grammar.d.ts.map +1 -0
- package/dist/agent-farm/servers/decisions/grammar.js +109 -0
- package/dist/agent-farm/servers/decisions/grammar.js.map +1 -0
- package/dist/agent-farm/servers/decisions/notice.d.ts +11 -0
- package/dist/agent-farm/servers/decisions/notice.d.ts.map +1 -0
- package/dist/agent-farm/servers/decisions/notice.js +18 -0
- package/dist/agent-farm/servers/decisions/notice.js.map +1 -0
- package/dist/agent-farm/servers/decisions/parse.d.ts +36 -0
- package/dist/agent-farm/servers/decisions/parse.d.ts.map +1 -0
- package/dist/agent-farm/servers/decisions/parse.js +308 -0
- package/dist/agent-farm/servers/decisions/parse.js.map +1 -0
- package/dist/agent-farm/servers/decisions/routes.d.ts +17 -0
- package/dist/agent-farm/servers/decisions/routes.d.ts.map +1 -0
- package/dist/agent-farm/servers/decisions/routes.js +160 -0
- package/dist/agent-farm/servers/decisions/routes.js.map +1 -0
- package/dist/agent-farm/servers/decisions/splice.d.ts +26 -0
- package/dist/agent-farm/servers/decisions/splice.d.ts.map +1 -0
- package/dist/agent-farm/servers/decisions/splice.js +120 -0
- package/dist/agent-farm/servers/decisions/splice.js.map +1 -0
- package/dist/agent-farm/servers/decisions/stamp.d.ts +4 -0
- package/dist/agent-farm/servers/decisions/stamp.d.ts.map +1 -0
- package/dist/agent-farm/servers/decisions/stamp.js +171 -0
- package/dist/agent-farm/servers/decisions/stamp.js.map +1 -0
- package/dist/agent-farm/servers/gate-profiles.d.ts +23 -2
- package/dist/agent-farm/servers/gate-profiles.d.ts.map +1 -1
- package/dist/agent-farm/servers/gate-profiles.js +43 -2
- package/dist/agent-farm/servers/gate-profiles.js.map +1 -1
- package/dist/agent-farm/servers/ide-forward.d.ts +62 -0
- package/dist/agent-farm/servers/ide-forward.d.ts.map +1 -0
- package/dist/agent-farm/servers/ide-forward.js +274 -0
- package/dist/agent-farm/servers/ide-forward.js.map +1 -0
- package/dist/agent-farm/servers/ide-server.d.ts +68 -0
- package/dist/agent-farm/servers/ide-server.d.ts.map +1 -0
- package/dist/agent-farm/servers/ide-server.js +281 -0
- package/dist/agent-farm/servers/ide-server.js.map +1 -0
- package/dist/agent-farm/servers/mailbox-delivery.d.ts +213 -4
- package/dist/agent-farm/servers/mailbox-delivery.d.ts.map +1 -1
- package/dist/agent-farm/servers/mailbox-delivery.js +489 -68
- package/dist/agent-farm/servers/mailbox-delivery.js.map +1 -1
- package/dist/agent-farm/servers/mailbox-wiring.d.ts +18 -4
- package/dist/agent-farm/servers/mailbox-wiring.d.ts.map +1 -1
- package/dist/agent-farm/servers/mailbox-wiring.js +94 -21
- package/dist/agent-farm/servers/mailbox-wiring.js.map +1 -1
- package/dist/agent-farm/servers/message-write.d.ts +138 -11
- package/dist/agent-farm/servers/message-write.d.ts.map +1 -1
- package/dist/agent-farm/servers/message-write.js +144 -35
- package/dist/agent-farm/servers/message-write.js.map +1 -1
- package/dist/agent-farm/servers/overview.d.ts +32 -15
- package/dist/agent-farm/servers/overview.d.ts.map +1 -1
- package/dist/agent-farm/servers/overview.js +181 -103
- package/dist/agent-farm/servers/overview.js.map +1 -1
- package/dist/agent-farm/servers/render-gate.d.ts +53 -0
- package/dist/agent-farm/servers/render-gate.d.ts.map +1 -1
- package/dist/agent-farm/servers/render-gate.js +135 -24
- package/dist/agent-farm/servers/render-gate.js.map +1 -1
- package/dist/agent-farm/servers/session-submit.d.ts +7 -4
- package/dist/agent-farm/servers/session-submit.d.ts.map +1 -1
- package/dist/agent-farm/servers/session-submit.js +7 -4
- package/dist/agent-farm/servers/session-submit.js.map +1 -1
- package/dist/agent-farm/servers/tower-cron.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-cron.js +4 -1
- package/dist/agent-farm/servers/tower-cron.js.map +1 -1
- package/dist/agent-farm/servers/tower-instances.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-instances.js +6 -7
- package/dist/agent-farm/servers/tower-instances.js.map +1 -1
- package/dist/agent-farm/servers/tower-routes.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-routes.js +116 -18
- package/dist/agent-farm/servers/tower-routes.js.map +1 -1
- package/dist/agent-farm/servers/tower-server.js +64 -7
- package/dist/agent-farm/servers/tower-server.js.map +1 -1
- package/dist/agent-farm/servers/tower-terminals.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-terminals.js +53 -8
- package/dist/agent-farm/servers/tower-terminals.js.map +1 -1
- package/dist/agent-farm/servers/tower-websocket.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-websocket.js +18 -1
- package/dist/agent-farm/servers/tower-websocket.js.map +1 -1
- package/dist/agent-farm/utils/message-format.d.ts +8 -0
- package/dist/agent-farm/utils/message-format.d.ts.map +1 -1
- package/dist/agent-farm/utils/message-format.js +21 -6
- package/dist/agent-farm/utils/message-format.js.map +1 -1
- package/dist/agent-farm/utils/port.d.ts +22 -0
- package/dist/agent-farm/utils/port.d.ts.map +1 -0
- package/dist/agent-farm/utils/port.js +35 -0
- package/dist/agent-farm/utils/port.js.map +1 -0
- package/dist/agent-farm/utils/server-utils.d.ts +26 -0
- package/dist/agent-farm/utils/server-utils.d.ts.map +1 -1
- package/dist/agent-farm/utils/server-utils.js +36 -0
- package/dist/agent-farm/utils/server-utils.js.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands/consult/index.d.ts +20 -1
- package/dist/commands/consult/index.d.ts.map +1 -1
- package/dist/commands/consult/index.js +117 -3
- package/dist/commands/consult/index.js.map +1 -1
- package/dist/commands/consult/tree-tripwire.d.ts +177 -0
- package/dist/commands/consult/tree-tripwire.d.ts.map +1 -0
- package/dist/commands/consult/tree-tripwire.js +356 -0
- package/dist/commands/consult/tree-tripwire.js.map +1 -0
- package/dist/commands/doctor.d.ts +69 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +163 -0
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/generate-image.d.ts +5 -0
- package/dist/commands/generate-image.d.ts.map +1 -1
- package/dist/commands/generate-image.js +225 -4
- package/dist/commands/generate-image.js.map +1 -1
- package/dist/commands/porch/checks.d.ts +7 -1
- package/dist/commands/porch/checks.d.ts.map +1 -1
- package/dist/commands/porch/checks.js +77 -14
- package/dist/commands/porch/checks.js.map +1 -1
- package/dist/commands/porch/index.d.ts +38 -1
- package/dist/commands/porch/index.d.ts.map +1 -1
- package/dist/commands/porch/index.js +79 -43
- package/dist/commands/porch/index.js.map +1 -1
- package/dist/commands/porch/protocol.d.ts +4 -3
- package/dist/commands/porch/protocol.d.ts.map +1 -1
- package/dist/commands/porch/protocol.js +32 -5
- package/dist/commands/porch/protocol.js.map +1 -1
- package/dist/commands/porch/types.d.ts +2 -0
- package/dist/commands/porch/types.d.ts.map +1 -1
- package/dist/lib/agent-env.d.ts +95 -0
- package/dist/lib/agent-env.d.ts.map +1 -0
- package/dist/lib/agent-env.js +137 -0
- package/dist/lib/agent-env.js.map +1 -0
- package/dist/lib/config.d.ts +8 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/forge-contracts.d.ts +10 -0
- package/dist/lib/forge-contracts.d.ts.map +1 -1
- package/dist/lib/forge-contracts.js.map +1 -1
- package/dist/lib/forge-rate-limit.d.ts +45 -0
- package/dist/lib/forge-rate-limit.d.ts.map +1 -0
- package/dist/lib/forge-rate-limit.js +89 -0
- package/dist/lib/forge-rate-limit.js.map +1 -0
- package/dist/lib/forge.d.ts +28 -0
- package/dist/lib/forge.d.ts.map +1 -1
- package/dist/lib/forge.js +63 -10
- package/dist/lib/forge.js.map +1 -1
- package/dist/lib/github.d.ts +13 -1
- package/dist/lib/github.d.ts.map +1 -1
- package/dist/lib/github.js +58 -15
- package/dist/lib/github.js.map +1 -1
- package/dist/lib/test-env.d.ts +17 -0
- package/dist/lib/test-env.d.ts.map +1 -1
- package/dist/lib/test-env.js +20 -0
- package/dist/lib/test-env.js.map +1 -1
- package/dist/terminal/pty-session.d.ts +122 -4
- package/dist/terminal/pty-session.d.ts.map +1 -1
- package/dist/terminal/pty-session.js +142 -7
- package/dist/terminal/pty-session.js.map +1 -1
- package/dist/terminal/session-manager.d.ts +23 -2
- package/dist/terminal/session-manager.d.ts.map +1 -1
- package/dist/terminal/session-manager.js +115 -36
- package/dist/terminal/session-manager.js.map +1 -1
- package/dist/terminal/session-screen.d.ts +34 -5
- package/dist/terminal/session-screen.d.ts.map +1 -1
- package/dist/terminal/session-screen.js +52 -6
- package/dist/terminal/session-screen.js.map +1 -1
- package/dist/terminal/terminal-replies.d.ts +102 -0
- package/dist/terminal/terminal-replies.d.ts.map +1 -0
- package/dist/terminal/terminal-replies.js +181 -0
- package/dist/terminal/terminal-replies.js.map +1 -0
- package/package.json +4 -4
- package/scripts/forge/github/pr-list.sh +6 -2
- package/scripts/forge/github/pr-search.sh +4 -2
- package/scripts/forge/gitlab/issue-search.sh +1 -0
- package/scripts/forge/gitlab/pr-search.sh +35 -2
- package/scripts/forge/linear/auth-status.sh +1 -0
- package/scripts/forge/linear/issue-comment.sh +1 -0
- package/scripts/forge/linear/issue-list.sh +1 -0
- package/scripts/forge/linear/issue-search.sh +1 -0
- package/scripts/forge/linear/issue-view.sh +1 -0
- package/scripts/forge/linear/recently-closed.sh +1 -0
- package/scripts/forge/linear/user-identity.sh +1 -0
- package/skeleton/.claude/skills/afx/SKILL.md +15 -0
- package/skeleton/.claude/skills/arch-init/SKILL.md +56 -9
- package/skeleton/.claude/skills/arch-save/SKILL.md +100 -9
- package/skeleton/.claude/skills/consult/SKILL.md +9 -0
- package/skeleton/.claude/skills/generate-image/SKILL.md +19 -2
- package/skeleton/.claude/skills/porch/SKILL.md +18 -0
- package/skeleton/.codex/skills/afx/SKILL.md +15 -0
- package/skeleton/.codex/skills/arch-init/SKILL.md +56 -9
- package/skeleton/.codex/skills/arch-save/SKILL.md +100 -9
- package/skeleton/.codex/skills/consult/SKILL.md +9 -0
- package/skeleton/.codex/skills/generate-image/SKILL.md +19 -2
- package/skeleton/.codex/skills/porch/SKILL.md +18 -0
- package/skeleton/protocol-schema.json +6 -0
- package/skeleton/protocols/maintain/protocol.md +5 -0
- package/skeleton/protocols/pir/prompts/review.md +0 -1
- package/skeleton/protocols/protocol-schema.json +6 -0
- package/skeleton/resources/commands/agent-farm.md +71 -2
- package/skeleton/resources/commands/consult.md +9 -2
- package/skeleton/roles/consultant.md +32 -0
- package/skeleton/templates/AGENTS.md +1 -1
- package/skeleton/templates/CLAUDE.md +1 -1
- package/skeleton/templates/cheatsheet.md +1 -1
- package/dashboard-dist/assets/index-CUIjS_Vb.js +0 -199
- package/dashboard-dist/assets/index-CUIjS_Vb.js.map +0 -1
- package/dashboard-dist/assets/index-DnYLy5C_.css +0 -32
|
@@ -1,17 +1,113 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Paced message writing for PTY sessions (Bugfix #584).
|
|
2
|
+
* Paced message writing for PTY sessions (Bugfix #584, Issue #1567).
|
|
3
3
|
*
|
|
4
4
|
* Extracted to a shared module to avoid circular imports between
|
|
5
5
|
* tower-routes.ts and tower-cron.ts.
|
|
6
6
|
*/
|
|
7
7
|
import { trySubmitToSession, watchBypasses } from './session-submit.js';
|
|
8
|
-
// Messages longer than this threshold are written line-by-line with delays
|
|
9
|
-
// to prevent the receiving terminal from classifying the input as a paste
|
|
10
|
-
// and swallowing the final Enter.
|
|
11
|
-
const PACED_WRITE_LINE_THRESHOLD = 4;
|
|
12
|
-
const INTER_LINE_DELAY_MS = 10;
|
|
13
|
-
const PACED_ENTER_DELAY_MS = 80;
|
|
14
8
|
const SIMPLE_ENTER_DELAY_MS = 50;
|
|
9
|
+
/**
|
|
10
|
+
* Issue #1567 — why long frames are no longer handed to the PTY in one write.
|
|
11
|
+
*
|
|
12
|
+
* The kernel splits a large master-side write at the slave's input-queue high-water mark
|
|
13
|
+
* (TTYHOG − 2 = 1022 bytes on macOS). The receiving TUI reads the first ~1 KB as one chunk,
|
|
14
|
+
* its paste heuristic classifies that chunk as a paste and DISCARDS it, then types the
|
|
15
|
+
* remainder and the Enter normally — so the agent saw a mid-sentence tail-only fragment
|
|
16
|
+
* while every `write()` reported success. Measured on claude 2.1.263 (harness in
|
|
17
|
+
* `scripts/bugfix-1567-head-loss-harness.mts`, evidence in `codev/evidence/1567-head-loss/`):
|
|
18
|
+
* a 1,172-byte 3-line frame lost its head 14/20 times on an IDLE composer; a 1,000-byte frame
|
|
19
|
+
* never did. Two independent changes each measured 0 losses, and both are applied:
|
|
20
|
+
*
|
|
21
|
+
* 1. **No single write exceeds {@link PASTE_CHUNK_BYTES}** — comfortably under the queue
|
|
22
|
+
* limit, so the kernel never splits a read and the reader drains between writes.
|
|
23
|
+
* 2. **Long frames travel as ONE explicit bracketed paste** (`ESC[200~` … `ESC[201~`), so the
|
|
24
|
+
* TUI's paste heuristic never runs on chunk boundaries and newlines inside the body can
|
|
25
|
+
* never be read as Enter. The Enter is a separate write OUTSIDE the bracket, after a
|
|
26
|
+
* settle. Inside the bracket newlines travel as `\r`, which is what a terminal emulator
|
|
27
|
+
* emits on paste (xterm.js) and what claude's composer expects there — the same convention
|
|
28
|
+
* `apps/vscode/src/review-queue/queue.ts` already uses to type a review into a builder.
|
|
29
|
+
*
|
|
30
|
+
* This replaces the #584-era per-line pacing for frames of {@link BRACKET_MIN_LINES} lines or
|
|
31
|
+
* more, which was tuned against an older TUI's heuristic. Short frames keep the pre-existing
|
|
32
|
+
* single write + delayed Enter, byte for byte, so `--raw` slash commands and short sends are
|
|
33
|
+
* untouched.
|
|
34
|
+
*/
|
|
35
|
+
export const PASTE_CHUNK_BYTES = 512;
|
|
36
|
+
/** Gap between consecutive chunk writes; the reader drains a chunk in well under this. */
|
|
37
|
+
export const PASTE_CHUNK_GAP_MS = 5;
|
|
38
|
+
/** Settle between the paste's closing marker and the Enter that submits it (measured: 0/29 losses). */
|
|
39
|
+
export const PASTE_ENTER_DELAY_MS = 80;
|
|
40
|
+
/**
|
|
41
|
+
* Frames LONGER than this many bytes, or of {@link BRACKET_MIN_LINES} lines or more, are
|
|
42
|
+
* bracketed and chunked. Well under the 1,022-byte queue limit where the loss starts: the
|
|
43
|
+
* field's smallest confirmed truncations were ~500-byte bodies, and a bracketed short paste
|
|
44
|
+
* costs nothing on the measured harnesses.
|
|
45
|
+
*/
|
|
46
|
+
export const BRACKET_MIN_BYTES = 256;
|
|
47
|
+
/** The #584 threshold, kept: any frame of this many lines or more is never typed line by line. */
|
|
48
|
+
export const BRACKET_MIN_LINES = 4;
|
|
49
|
+
/** Gap between line pieces on the non-bracketed (opt-out) strategy — the #584 pacing. */
|
|
50
|
+
const INTER_LINE_DELAY_MS = 10;
|
|
51
|
+
export const PASTE_BEGIN = '\x1b[200~';
|
|
52
|
+
export const PASTE_END = '\x1b[201~';
|
|
53
|
+
export const BRACKETED_PASTE = { bracketedPaste: true };
|
|
54
|
+
export const PLAIN_CHUNKED = { bracketedPaste: false };
|
|
55
|
+
/**
|
|
56
|
+
* The write strategy for a gate profile's `app`. agy is the one modeled harness whose paste
|
|
57
|
+
* handling was not measurable (unauthenticated), so it keeps the per-line shape; anything
|
|
58
|
+
* else is bracketed. Unknown apps never reach the write edge (the gate holds `no-profile`).
|
|
59
|
+
*/
|
|
60
|
+
export function writeStrategyForApp(app) {
|
|
61
|
+
return app === 'agy' ? PLAIN_CHUNKED : BRACKETED_PASTE;
|
|
62
|
+
}
|
|
63
|
+
/** Does this frame take the bracketed/chunked path rather than the single short write? */
|
|
64
|
+
export function isLongFrame(message) {
|
|
65
|
+
return message.split('\n').length >= BRACKET_MIN_LINES || Buffer.byteLength(message, 'utf8') > BRACKET_MIN_BYTES;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Split `text` into pieces of at most `max` bytes, never inside a UTF-8 sequence (a split
|
|
69
|
+
* continuation byte would reach the TUI as two invalid characters).
|
|
70
|
+
*/
|
|
71
|
+
export function chunkForPty(text, max = PASTE_CHUNK_BYTES) {
|
|
72
|
+
const buf = Buffer.from(text, 'utf8');
|
|
73
|
+
const out = [];
|
|
74
|
+
for (let at = 0; at < buf.length;) {
|
|
75
|
+
let end = Math.min(buf.length, at + max);
|
|
76
|
+
while (end < buf.length && end > at && (buf[end] & 0xc0) === 0x80)
|
|
77
|
+
end--;
|
|
78
|
+
out.push(buf.subarray(at, end).toString('utf8'));
|
|
79
|
+
at = end;
|
|
80
|
+
}
|
|
81
|
+
return out;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* The pieces of a long frame, in write order, for a strategy. Bracketed: the body (newlines
|
|
85
|
+
* as `\r`) chunked, with the opening marker on the first piece and the closing marker on the
|
|
86
|
+
* last — the markers are never split across writes, so no chunk boundary can land inside an
|
|
87
|
+
* escape sequence, and every piece INCLUDING its marker stays within {@link PASTE_CHUNK_BYTES}.
|
|
88
|
+
* Plain: one piece per line (`\n` kept, as #584 wrote it), with any line over
|
|
89
|
+
* the chunk size split further.
|
|
90
|
+
*/
|
|
91
|
+
export function framePieces(message, strategy) {
|
|
92
|
+
if (strategy.bracketedPaste) {
|
|
93
|
+
// A literal paste marker inside the body (a pasted terminal log, say) would end or restart
|
|
94
|
+
// the paste mid-frame and let the remainder be typed as keys; strip both so the bracket
|
|
95
|
+
// we add is the only one the TUI sees.
|
|
96
|
+
const body = message.replace(/\r?\n/g, '\r').split(PASTE_BEGIN).join('').split(PASTE_END).join('');
|
|
97
|
+
// Chunk with room for the markers so NO write — first or last piece included — exceeds
|
|
98
|
+
// PASTE_CHUNK_BYTES on the wire.
|
|
99
|
+
const pieces = chunkForPty(body, PASTE_CHUNK_BYTES - PASTE_BEGIN.length - PASTE_END.length);
|
|
100
|
+
// A body that was NOTHING but markers is empty after stripping; still emit one (empty) paste
|
|
101
|
+
// so the frame is a well-formed no-op rather than the literal text "undefined".
|
|
102
|
+
if (pieces.length === 0)
|
|
103
|
+
pieces.push('');
|
|
104
|
+
pieces[0] = PASTE_BEGIN + pieces[0];
|
|
105
|
+
pieces[pieces.length - 1] += PASTE_END;
|
|
106
|
+
return pieces;
|
|
107
|
+
}
|
|
108
|
+
const lines = message.split('\n');
|
|
109
|
+
return lines.flatMap((line, i) => chunkForPty(i < lines.length - 1 ? line + '\n' : line));
|
|
110
|
+
}
|
|
15
111
|
/** ESC keystroke — ends the agent's current turn (Spec 1273). */
|
|
16
112
|
export const ESC = '\x1b';
|
|
17
113
|
/**
|
|
@@ -43,21 +139,22 @@ export function writeEscapeToSession(session, noEnter) {
|
|
|
43
139
|
return ESCAPE_ENTER_DELAY_MS;
|
|
44
140
|
}
|
|
45
141
|
/**
|
|
46
|
-
* Write a message to a PTY session
|
|
47
|
-
*
|
|
142
|
+
* Write a message to a PTY session (Bugfix #584, Issue #1567).
|
|
143
|
+
*
|
|
144
|
+
* Short frames (under {@link BRACKET_MIN_LINES} lines AND at most {@link BRACKET_MIN_BYTES}
|
|
145
|
+
* bytes): a single write, then Enter after 50 ms — unchanged since #584.
|
|
48
146
|
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
* after
|
|
147
|
+
* Long frames: {@link framePieces} written {@link PASTE_CHUNK_GAP_MS} apart (bracketed by
|
|
148
|
+
* default; see {@link WriteStrategy}), then Enter as its own write
|
|
149
|
+
* {@link PASTE_ENTER_DELAY_MS} after the last piece. The Enter is always outside the paste
|
|
150
|
+
* bracket, so a TUI that collapses the paste into a placard still submits it.
|
|
52
151
|
*
|
|
53
152
|
* @param delayOffset ms offset for all scheduled writes (used to serialize
|
|
54
153
|
* multiple messages to the same session without interleaving)
|
|
55
154
|
* @returns ms timestamp (from call time) when all writes complete
|
|
56
155
|
*/
|
|
57
|
-
export function writeMessageToSession(session, message, noEnter, delayOffset = 0) {
|
|
58
|
-
|
|
59
|
-
if (lines.length < PACED_WRITE_LINE_THRESHOLD) {
|
|
60
|
-
// Short messages: single write (existing behavior, works fine)
|
|
156
|
+
export function writeMessageToSession(session, message, noEnter, delayOffset = 0, strategy = BRACKETED_PASTE) {
|
|
157
|
+
if (!isLongFrame(message)) {
|
|
61
158
|
if (delayOffset === 0) {
|
|
62
159
|
session.write(message);
|
|
63
160
|
}
|
|
@@ -70,26 +167,23 @@ export function writeMessageToSession(session, message, noEnter, delayOffset = 0
|
|
|
70
167
|
}
|
|
71
168
|
return enterTime;
|
|
72
169
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (lineDelay === 0) {
|
|
80
|
-
session.write(text);
|
|
170
|
+
const pieces = framePieces(message, strategy);
|
|
171
|
+
const gap = strategy.bracketedPaste ? PASTE_CHUNK_GAP_MS : INTER_LINE_DELAY_MS;
|
|
172
|
+
for (let i = 0; i < pieces.length; i++) {
|
|
173
|
+
const at = delayOffset + i * gap;
|
|
174
|
+
if (at === 0) {
|
|
175
|
+
session.write(pieces[i]);
|
|
81
176
|
}
|
|
82
177
|
else {
|
|
83
|
-
setTimeout(() => session.write(
|
|
178
|
+
setTimeout(() => session.write(pieces[i]), at);
|
|
84
179
|
}
|
|
85
180
|
}
|
|
86
|
-
const
|
|
87
|
-
if (
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
return lastLineTime;
|
|
181
|
+
const lastPieceTime = delayOffset + (pieces.length - 1) * gap;
|
|
182
|
+
if (noEnter)
|
|
183
|
+
return lastPieceTime;
|
|
184
|
+
const enterTime = lastPieceTime + PASTE_ENTER_DELAY_MS;
|
|
185
|
+
setTimeout(() => session.write('\r'), enterTime);
|
|
186
|
+
return enterTime;
|
|
93
187
|
}
|
|
94
188
|
/**
|
|
95
189
|
* Paced write of a message (text + trailing Enter unless `noEnter`) performed as ONE
|
|
@@ -117,7 +211,7 @@ export function writeMessageToSession(session, message, noEnter, delayOffset = 0
|
|
|
117
211
|
* `submitToSession` schedules its own equal-offset sleep, so the Enter still executes
|
|
118
212
|
* first — which is what makes the per-agent serializer's completion-chaining real.
|
|
119
213
|
*/
|
|
120
|
-
export async function submitMessagePaced(session, message, noEnter, precheck, clock) {
|
|
214
|
+
export async function submitMessagePaced(session, message, noEnter, precheck, clock, strategy = BRACKETED_PASTE) {
|
|
121
215
|
// Fail LOUD on a missing id rather than keying the lock on `undefined`. Sessions reach
|
|
122
216
|
// this through structurally-typed ports, so a double without an id compiles fine and
|
|
123
217
|
// would silently collapse every per-terminal lock into one global lock — serialization
|
|
@@ -137,9 +231,17 @@ export async function submitMessagePaced(session, message, noEnter, precheck, cl
|
|
|
137
231
|
try {
|
|
138
232
|
let delivered = true;
|
|
139
233
|
let abort = null;
|
|
234
|
+
// Sampled inside the lock, immediately before the first byte (below), so the comparison
|
|
235
|
+
// spans exactly the paced write and not the lock wait that preceded it.
|
|
236
|
+
let inputSeqBefore = session.inputSeq;
|
|
237
|
+
// The origin is HARD-CODED here rather than forwarded through a parameter (Issue #1473).
|
|
238
|
+
// A one-arg function is assignable to a two-arg function type, so a wrapper that forgot to
|
|
239
|
+
// pass the origin along would compile cleanly — and its failure mode is the delivery
|
|
240
|
+
// counting its own bytes as human input, i.e. "mail never delivers". Removing the parameter
|
|
241
|
+
// removes the opportunity.
|
|
140
242
|
const tracked = {
|
|
141
243
|
write: (data) => {
|
|
142
|
-
const ok = session.write(data);
|
|
244
|
+
const ok = session.write(data, 'delivery');
|
|
143
245
|
if (!ok)
|
|
144
246
|
delivered = false;
|
|
145
247
|
return ok;
|
|
@@ -149,7 +251,8 @@ export async function submitMessagePaced(session, message, noEnter, precheck, cl
|
|
|
149
251
|
abort = precheck();
|
|
150
252
|
if (abort !== null)
|
|
151
253
|
return 0; // refused in-lock: not one byte goes out
|
|
152
|
-
|
|
254
|
+
inputSeqBefore = session.inputSeq;
|
|
255
|
+
return writeMessageToSession(tracked, message, noEnter, 0, strategy);
|
|
153
256
|
}, clock);
|
|
154
257
|
if (!ran)
|
|
155
258
|
return { status: 'contended' };
|
|
@@ -162,6 +265,12 @@ export async function submitMessagePaced(session, message, noEnter, precheck, cl
|
|
|
162
265
|
return { status: 'dropped' };
|
|
163
266
|
if (bypasses.raced())
|
|
164
267
|
return { status: 'preempted' };
|
|
268
|
+
// The prechecks close everything up to the first byte; between the first byte and the
|
|
269
|
+
// trailing Enter there is still an 80 ms-to-seconds window, and by then the bytes are out.
|
|
270
|
+
// So this is a REPORTING signal — flag it and let the caller tell the operator, rather than
|
|
271
|
+
// hold and re-write a message that may well have landed (#1584). Omitted when false.
|
|
272
|
+
if (session.inputSeq !== inputSeqBefore)
|
|
273
|
+
return { status: 'written', racedByInput: true };
|
|
165
274
|
return { status: 'written' };
|
|
166
275
|
}
|
|
167
276
|
finally {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-write.js","sourceRoot":"","sources":["../../../src/agent-farm/servers/message-write.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAoB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"message-write.js","sourceRoot":"","sources":["../../../src/agent-farm/servers/message-write.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* mode when the `gh` CLI is unavailable.
|
|
8
8
|
*/
|
|
9
9
|
import type { ForgeIssueListItem } from '../../lib/github.js';
|
|
10
|
+
import { type RateLimitProbe } from '../../lib/forge-rate-limit.js';
|
|
10
11
|
import type { PlanPhase, OverviewBuilder, OverviewBacklogItem, OverviewData } from '@cluesmith/codev-types';
|
|
11
12
|
interface ParsedStatus {
|
|
12
13
|
id: string;
|
|
@@ -57,6 +58,7 @@ export declare function calculateProgress(parsed: ParsedStatus, workspaceRoot?:
|
|
|
57
58
|
* Each phase gets an equal share of 100%, with 'verified'/'complete' always = 100.
|
|
58
59
|
*/
|
|
59
60
|
export declare function calculateEvenProgress(phase: string, phases: string[]): number;
|
|
61
|
+
/** Human-readable label for the gate the builder is blocked on, or null. */
|
|
60
62
|
export declare function detectBlocked(parsed: ParsedStatus): string | null;
|
|
61
63
|
/**
|
|
62
64
|
* Canonical gate name (e.g. "plan-approval") for the gate the builder is
|
|
@@ -68,9 +70,9 @@ export declare function detectBlockedGate(parsed: ParsedStatus): string | null;
|
|
|
68
70
|
* Detect when the current blocked gate was first requested.
|
|
69
71
|
* Returns the ISO timestamp string or null if not blocked.
|
|
70
72
|
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
73
|
+
* Shares `findBlockedGate` with `detectBlocked` / `detectBlockedGate` so the
|
|
74
|
+
* gate set lives in exactly one place (#927 removed a previously-separate
|
|
75
|
+
* hardcoded array, which was a silent drift hazard).
|
|
74
76
|
*/
|
|
75
77
|
export declare function detectBlockedSince(parsed: ParsedStatus): string | null;
|
|
76
78
|
/**
|
|
@@ -161,15 +163,28 @@ export declare function readFeedbackMode(workspaceRoot: string): 'forward' | 'qu
|
|
|
161
163
|
* Derive backlog from open GitHub issues cross-referenced with specs and builders.
|
|
162
164
|
*/
|
|
163
165
|
export declare function deriveBacklog(issues: ForgeIssueListItem[], workspaceRoot: string, activeBuilderIssues: Set<string>, prLinkedIssues: Set<string>): OverviewBacklogItem[];
|
|
166
|
+
export interface OverviewCacheOptions {
|
|
167
|
+
/** Clock, injectable for tests. */
|
|
168
|
+
now?: () => number;
|
|
169
|
+
/** Reset probe run once per fresh suspension (Tower passes the gh probe). */
|
|
170
|
+
probe?: RateLimitProbe;
|
|
171
|
+
}
|
|
164
172
|
export declare class OverviewCache {
|
|
165
173
|
private prCache;
|
|
166
174
|
private issueCache;
|
|
167
175
|
private closedCache;
|
|
168
176
|
private mergedPRCache;
|
|
169
177
|
private currentUserCache;
|
|
178
|
+
/** Single-flight per `<workspace>:<concept>` (#1645). */
|
|
179
|
+
private inflight;
|
|
180
|
+
/** Escalating failure window per `<workspace>:<budget>`. */
|
|
181
|
+
private failureWindows;
|
|
182
|
+
/** Epoch of the last invalidate(); open-list entries fetched before it are stale once debounced. */
|
|
183
|
+
private invalidatedAt;
|
|
184
|
+
private readonly limiter;
|
|
185
|
+
private readonly now;
|
|
186
|
+
constructor(options?: OverviewCacheOptions);
|
|
170
187
|
private resolvedEnrichment;
|
|
171
|
-
private readonly TTL;
|
|
172
|
-
private readonly USER_TTL;
|
|
173
188
|
/**
|
|
174
189
|
* Build the overview response. Aggregates builder state, PRs, and backlog.
|
|
175
190
|
*
|
|
@@ -180,20 +195,22 @@ export declare class OverviewCache {
|
|
|
180
195
|
*/
|
|
181
196
|
getOverview(workspaceRoot: string, activeBuilderRoleIds?: Set<string>): Promise<OverviewData>;
|
|
182
197
|
/**
|
|
183
|
-
*
|
|
198
|
+
* Mark the open lists (PRs, issues) stale. Porch, cleanup and the VS Code
|
|
199
|
+
* review queue call this after every mutation, so it is not a human signal
|
|
200
|
+
* (#1645): it never clears a suspension or a cached failure, never touches
|
|
201
|
+
* the search or identity caches, and a list is refetched for it at most once
|
|
202
|
+
* per `INVALIDATE_DEBOUNCE_MS` per workspace.
|
|
184
203
|
*/
|
|
185
204
|
invalidate(): void;
|
|
186
|
-
private fetchPRsCached;
|
|
187
|
-
private fetchIssuesCached;
|
|
188
205
|
/**
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
* Only successful resolutions are cached, so a transient failure (gh
|
|
192
|
-
* logged out, offline) self-heals on the next overview poll.
|
|
206
|
+
* Serve `concept` for `cwd` from cache, or dispatch exactly one fetch.
|
|
207
|
+
* `listCache` entries additionally honour invalidate() (debounced).
|
|
193
208
|
*/
|
|
194
|
-
private
|
|
195
|
-
|
|
196
|
-
private
|
|
209
|
+
private cachedFetch;
|
|
210
|
+
/** Run the concept once and record the outcome. Never rejects. */
|
|
211
|
+
private dispatch;
|
|
212
|
+
/** Current failure window for a key; escalates once per elapsed window, not per failure. */
|
|
213
|
+
private failureWindow;
|
|
197
214
|
}
|
|
198
215
|
export {};
|
|
199
216
|
//# sourceMappingURL=overview.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overview.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/servers/overview.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"overview.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/servers/overview.ts"],"names":[],"mappings":"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"}
|