ftown 0.21.0 → 0.25.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/dist/attention-events.d.ts +1 -1
- package/dist/attention-store.d.ts +3 -0
- package/dist/attention-store.js +25 -1
- package/dist/attention-store.js.map +1 -1
- package/dist/centrifugo-client.d.ts +14 -1
- package/dist/centrifugo-client.js +38 -4
- package/dist/centrifugo-client.js.map +1 -1
- package/dist/command-rpc.d.ts +2 -0
- package/dist/command-rpc.js +55 -9
- package/dist/command-rpc.js.map +1 -1
- package/dist/direct-transport/loopback-server.d.ts +10 -3
- package/dist/direct-transport/loopback-server.js +20 -4
- package/dist/direct-transport/loopback-server.js.map +1 -1
- package/dist/direct-transport/peer-manager.d.ts +8 -3
- package/dist/direct-transport/peer-manager.js +20 -5
- package/dist/direct-transport/peer-manager.js.map +1 -1
- package/dist/file-stamp.d.ts +33 -0
- package/dist/file-stamp.js +35 -0
- package/dist/file-stamp.js.map +1 -0
- package/dist/identity-reset.d.ts +3 -1
- package/dist/identity-reset.js +27 -5
- package/dist/identity-reset.js.map +1 -1
- package/dist/index.js +31 -37
- package/dist/index.js.map +1 -1
- package/dist/ledger-pairing-client.d.ts +1 -1
- package/dist/ledger-pairing-client.js +5 -3
- package/dist/ledger-pairing-client.js.map +1 -1
- package/dist/ledger-relay.d.ts +42 -7
- package/dist/ledger-relay.js +175 -33
- package/dist/ledger-relay.js.map +1 -1
- package/dist/ledger-reoffer.d.ts +56 -0
- package/dist/ledger-reoffer.js +210 -0
- package/dist/ledger-reoffer.js.map +1 -0
- package/dist/ledger-startup.d.ts +30 -5
- package/dist/ledger-startup.js +40 -10
- package/dist/ledger-startup.js.map +1 -1
- package/dist/local-api-server.d.ts +3 -0
- package/dist/local-api-server.js +68 -6
- package/dist/local-api-server.js.map +1 -1
- package/dist/mail-delivery.d.ts +26 -3
- package/dist/mail-delivery.js +65 -7
- package/dist/mail-delivery.js.map +1 -1
- package/dist/mail-store.d.ts +15 -1
- package/dist/mail-store.js +78 -16
- package/dist/mail-store.js.map +1 -1
- package/dist/outbound-pipeline-types.d.ts +5 -2
- package/dist/outbound-pipeline-types.js.map +1 -1
- package/dist/preview-protocol.d.ts +19 -3
- package/dist/preview-protocol.js +14 -0
- package/dist/preview-protocol.js.map +1 -1
- package/dist/relay-token.d.ts +6 -0
- package/dist/relay-token.js +9 -1
- package/dist/relay-token.js.map +1 -1
- package/dist/security/bridge/ledger-rpc.d.ts +34 -0
- package/dist/security/bridge/ledger-rpc.js +58 -0
- package/dist/security/bridge/ledger-rpc.js.map +1 -0
- package/dist/security/bridge/ledger-store.d.ts +82 -13
- package/dist/security/bridge/ledger-store.js +394 -54
- package/dist/security/bridge/ledger-store.js.map +1 -1
- package/dist/security/bridge/permissions.js +2 -1
- package/dist/security/bridge/permissions.js.map +1 -1
- package/dist/security/bridge/policy.d.ts +5 -1
- package/dist/security/bridge/policy.js +17 -0
- package/dist/security/bridge/policy.js.map +1 -1
- package/dist/security/bridge/security.d.ts +148 -10
- package/dist/security/bridge/security.js +270 -65
- package/dist/security/bridge/security.js.map +1 -1
- package/dist/security/crypto.d.ts +2 -0
- package/dist/security/crypto.js +43 -4
- package/dist/security/crypto.js.map +1 -1
- package/dist/security/ledger/announce.d.ts +32 -0
- package/dist/security/ledger/announce.js +101 -0
- package/dist/security/ledger/announce.js.map +1 -0
- package/dist/security/ledger/ledger.d.ts +107 -14
- package/dist/security/ledger/ledger.js +364 -83
- package/dist/security/ledger/ledger.js.map +1 -1
- package/dist/security/ledger/proof.d.ts +12 -0
- package/dist/security/ledger/proof.js +40 -8
- package/dist/security/ledger/proof.js.map +1 -1
- package/dist/security/ledger/protocol.d.ts +14 -1
- package/dist/security/ledger/protocol.js.map +1 -1
- package/dist/session-controller.d.ts +9 -3
- package/dist/session-controller.js +120 -20
- package/dist/session-controller.js.map +1 -1
- package/dist/session-inbox-protocol.d.ts +2 -0
- package/dist/session-preview.d.ts +20 -5
- package/dist/session-preview.js +185 -37
- package/dist/session-preview.js.map +1 -1
- package/dist/session-store.d.ts +22 -0
- package/dist/session-store.js +180 -13
- package/dist/session-store.js.map +1 -1
- package/dist/sessions-commands.js +41 -7
- package/dist/sessions-commands.js.map +1 -1
- package/dist/terminal-manager.d.ts +8 -0
- package/dist/terminal-manager.js +23 -1
- package/dist/terminal-manager.js.map +1 -1
- package/dist/terminal-output.d.ts +34 -0
- package/dist/terminal-output.js +68 -0
- package/dist/terminal-output.js.map +1 -0
- package/dist/terminal-pump.d.ts +48 -5
- package/dist/terminal-pump.js +143 -20
- package/dist/terminal-pump.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/opencode-plugin/ftown.js +15 -2
- package/package.json +2 -2
- package/skills/ftown/SKILL.md +18 -7
- package/skills/ftown/references/sessions.md +35 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal-manager.js","sourceRoot":"","sources":["../src/terminal-manager.ts"],"names":[],"mappings":"AAAA,OAAO,aAAgD,MAAM,iBAAiB,CAAC;AAC/E,OAAO,cAAc,MAAM,wBAAwB,CAAC;AAEpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAC;AACnC,MAAM,EAAE,cAAc,EAAE,GAAG,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"terminal-manager.js","sourceRoot":"","sources":["../src/terminal-manager.ts"],"names":[],"mappings":"AAAA,OAAO,aAAgD,MAAM,iBAAiB,CAAC;AAC/E,OAAO,cAAc,MAAM,wBAAwB,CAAC;AAEpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAC;AACnC,MAAM,EAAE,cAAc,EAAE,GAAG,cAAc,CAAC;AA8B1C;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,GAAW,EAAE,IAAI,GAAG,GAAG,EAAE,IAAI,GAAG,EAAE,EAAE,UAAU,GAAG,KAAK;IAC7F,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IACpB,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC;IAClF,IAAI,CAAC;QACH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;QACnE,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC;QACtC,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QACzE,CAAC;QACD,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,IAAI,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC;gBAAE,SAAS;YAChG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;QACD,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE;YAAE,SAAS,CAAC,GAAG,EAAE,CAAC;QACvF,OAAO,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;YAAS,CAAC;QACT,QAAQ,CAAC,OAAO,EAAE,CAAC;IACrB,CAAC;AACH,CAAC;AAED,MAAM,OAAO,eAAe;IACT,SAAS,GAAiC,IAAI,GAAG,EAAE,CAAC;IACpD,UAAU,CAAS;IACnB,IAAI,CAAS;IAE9B,YAAY,UAAU,GAAG,KAAK,EAAE,IAAI,GAAG,GAAG;QACxC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAEO,cAAc,CAAC,SAAiB;QACtC,IAAI,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC5C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC;gBAC5B,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,IAAI,EAAE,EAAE;gBACR,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,gBAAgB,EAAE,IAAI;gBACtB,KAAK,EAAE,iBAAiB;aACzB,CAAC,CAAC;YACH,MAAM,UAAU,GAAG,IAAI,cAAc,EAAE,CAAC;YACxC,QAAQ,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;YAC/B,OAAO,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC;YAC5D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACzC,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,SAAiB,EAAE,IAAY;QACnC,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QAC/C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACzC,CAAC;IAED;;;;;;OAMG;IACH,UAAU,CAAC,SAAiB,EAAE,IAAgB;QAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC9C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,IAAI,EAAE,CAAC;YACP,OAAO;QACT,CAAC;QACD,MAAM,MAAM,GAAG,GAAS,EAAE;YACxB,IAAI,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC;gBAAE,IAAI,EAAE,CAAC;QAClD,CAAC,CAAC;QACF,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC;IAED,SAAS,CAAC,SAAiB,EAAE,UAAmB;QAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC9C,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,CAAC;QACxB,OAAO,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,SAAS,CAAC,SAAiB,EAAE,MAAM,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI;QACnD,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC9C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QACrD,CAAC;QAED,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;QACzD,MAAM,QAAQ,GAAa,EAAE,CAAC;QAE9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACvD,IAAI,IAAI,EAAE,CAAC;gBACT,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;QAED,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC;QACrD,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC9C,CAAC;IAED;;;OAGG;IACH,QAAQ,CAAC,SAAiB;QACxB,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC9C,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,CAAC;QACxB,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;QACzD,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACvD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACvD,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,CAAC,SAAiB,EAAE,MAAc;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QAC/C,OAAO,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,CAAC,SAAiB;QACvB,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC9C,IAAI,CAAC,OAAO;YAAE,OAAO,SAAS,CAAC;QAC/B,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;IACtE,CAAC;IAED,MAAM,CAAC,SAAiB,EAAE,IAAY,EAAE,IAAY;QAClD,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC9C,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAED,OAAO,CAAC,SAAiB;QACvB,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC9C,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;YAC3B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACjC,KAAK,MAAM,MAAM,IAAI,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC;gBAAE,MAAM,EAAE,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,GAAG,CAAC,SAAiB;QACnB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACvC,CAAC;CACF"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ProcessRunner } from './claude-runner.js';
|
|
2
|
+
import type { SessionStore } from './session-store.js';
|
|
3
|
+
import type { TerminalManager } from './terminal-manager.js';
|
|
4
|
+
import { TerminalPump, type TerminalPumpDeps } from './terminal-pump.js';
|
|
5
|
+
export interface TerminalOutputDeps {
|
|
6
|
+
store: TerminalPumpDeps['store'] & Pick<SessionStore, 'setPendingTerminalFlush'>;
|
|
7
|
+
terminalManager: Pick<TerminalManager, 'write' | 'destroy' | 'serialize' | 'whenParsed'>;
|
|
8
|
+
runner: Pick<ProcessRunner, 'on' | 'stopAll'>;
|
|
9
|
+
/** Fan-out to direct peers and, when remotely watched, Centrifugo. */
|
|
10
|
+
router: {
|
|
11
|
+
hasAttachedPeers(sessionId: string): boolean;
|
|
12
|
+
publishTerminalData(sessionId: string, data: string): void;
|
|
13
|
+
publishTerminalScreen(sessionId: string, screen: string): void;
|
|
14
|
+
};
|
|
15
|
+
watchRegistry: {
|
|
16
|
+
hasWatchers(sessionId: string): boolean;
|
|
17
|
+
};
|
|
18
|
+
lifecycle: Pick<TerminalPumpDeps, 'publishSessionUpdate' | 'publishHookEvent' | 'unregisterSession' | 'collectUsage'>;
|
|
19
|
+
}
|
|
20
|
+
export interface TerminalOutput {
|
|
21
|
+
pump: TerminalPump;
|
|
22
|
+
/** Screen for a direct/loopback peer that attaches; `deliver` joins it to the stream. */
|
|
23
|
+
attachScreen(sessionId: string, deliver: (screen: string) => void): void;
|
|
24
|
+
/** Full screen resync for every viewer of the session. */
|
|
25
|
+
publishScreenDump(sessionId: string): void;
|
|
26
|
+
/** Stop the runner's PTY clients and persist all output still in the pump. */
|
|
27
|
+
stop(): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Wires the terminal output path: runner -> pump -> store + transports, the
|
|
31
|
+
* watched/unwatched cadence, and every reader that needs output which is still
|
|
32
|
+
* coalescing (screen snapshots, terminal.log readers, shutdown).
|
|
33
|
+
*/
|
|
34
|
+
export declare function createTerminalOutput(deps: TerminalOutputDeps): TerminalOutput;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { TerminalPump } from './terminal-pump.js';
|
|
2
|
+
/** Scrollback lines replayed to a viewer that attaches or asks for a resync. */
|
|
3
|
+
const ATTACH_SCROLLBACK_LINES = 20000;
|
|
4
|
+
/**
|
|
5
|
+
* Cap for a published screen dump. Accounts for ~50% JSON-encoding inflation on
|
|
6
|
+
* ANSI-heavy buffers (each \x1b expands 1 -> 6 bytes), keeping the on-wire
|
|
7
|
+
* Centrifugo frame under websocket_message_size_limit.
|
|
8
|
+
*/
|
|
9
|
+
const MAX_SCREEN_DUMP_BYTES = 2_500_000;
|
|
10
|
+
/**
|
|
11
|
+
* RIS (full reset), sent in-band at the head of every screen. A viewer resets
|
|
12
|
+
* its terminal when a screen arrives, but that reset is synchronous while its
|
|
13
|
+
* terminal parses writes asynchronously: output received just before the screen
|
|
14
|
+
* is still queued and would be painted AFTER the reset, under the screen's
|
|
15
|
+
* content (wrong cursor, repeated text, later lines overwritten). Carrying the
|
|
16
|
+
* reset inside the data orders it after everything the viewer queued earlier.
|
|
17
|
+
*/
|
|
18
|
+
const SCREEN_RESET = '\x1bc';
|
|
19
|
+
/**
|
|
20
|
+
* Wires the terminal output path: runner -> pump -> store + transports, the
|
|
21
|
+
* watched/unwatched cadence, and every reader that needs output which is still
|
|
22
|
+
* coalescing (screen snapshots, terminal.log readers, shutdown).
|
|
23
|
+
*/
|
|
24
|
+
export function createTerminalOutput(deps) {
|
|
25
|
+
const { store, terminalManager, runner, router, watchRegistry } = deps;
|
|
26
|
+
const pump = new TerminalPump({
|
|
27
|
+
store,
|
|
28
|
+
terminalManager,
|
|
29
|
+
publishTerminalData: (sessionId, data) => router.publishTerminalData(sessionId, data),
|
|
30
|
+
isWatched: (sessionId) => router.hasAttachedPeers(sessionId) || watchRegistry.hasWatchers(sessionId),
|
|
31
|
+
...deps.lifecycle,
|
|
32
|
+
});
|
|
33
|
+
pump.attach(runner);
|
|
34
|
+
// terminal.log readers (screen/grep fallbacks, clear) see pending output too.
|
|
35
|
+
store.setPendingTerminalFlush((sessionId) => pump.flush(sessionId));
|
|
36
|
+
return {
|
|
37
|
+
pump,
|
|
38
|
+
attachScreen(sessionId, deliver) {
|
|
39
|
+
pump.snapshot(sessionId, () => deliver(SCREEN_RESET + (terminalManager.serialize(sessionId, ATTACH_SCROLLBACK_LINES) ?? '')));
|
|
40
|
+
},
|
|
41
|
+
publishScreenDump(sessionId) {
|
|
42
|
+
pump.snapshot(sessionId, () => {
|
|
43
|
+
// Phase 1: viewport-only dump (~rows*cols bytes) for instant render.
|
|
44
|
+
const viewportRaw = terminalManager.serialize(sessionId, 0);
|
|
45
|
+
if (viewportRaw) {
|
|
46
|
+
router.publishTerminalScreen(sessionId, SCREEN_RESET + viewportRaw);
|
|
47
|
+
}
|
|
48
|
+
// Phase 2: full dump with scrollback. Client re-renders on top of phase 1.
|
|
49
|
+
let scrollback = ATTACH_SCROLLBACK_LINES;
|
|
50
|
+
let raw = terminalManager.serialize(sessionId, scrollback);
|
|
51
|
+
while (raw && Buffer.byteLength(raw, 'utf8') > MAX_SCREEN_DUMP_BYTES && scrollback > 100) {
|
|
52
|
+
scrollback = Math.floor(scrollback / 2);
|
|
53
|
+
raw = terminalManager.serialize(sessionId, scrollback);
|
|
54
|
+
}
|
|
55
|
+
if (!raw)
|
|
56
|
+
return;
|
|
57
|
+
if (raw === viewportRaw)
|
|
58
|
+
return;
|
|
59
|
+
router.publishTerminalScreen(sessionId, SCREEN_RESET + raw);
|
|
60
|
+
});
|
|
61
|
+
},
|
|
62
|
+
async stop() {
|
|
63
|
+
runner.stopAll();
|
|
64
|
+
await pump.drain();
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=terminal-output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-output.js","sourceRoot":"","sources":["../src/terminal-output.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAyB,MAAM,oBAAoB,CAAC;AAEzE,gFAAgF;AAChF,MAAM,uBAAuB,GAAG,KAAK,CAAC;AACtC;;;;GAIG;AACH,MAAM,qBAAqB,GAAG,SAAS,CAAC;AACxC;;;;;;;GAOG;AACH,MAAM,YAAY,GAAG,OAAO,CAAC;AA0B7B;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAwB;IAC3D,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC;IACvE,MAAM,IAAI,GAAG,IAAI,YAAY,CAAC;QAC5B,KAAK;QACL,eAAe;QACf,mBAAmB,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC;QACrF,SAAS,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,SAAS,CAAC,IAAI,aAAa,CAAC,WAAW,CAAC,SAAS,CAAC;QACpG,GAAG,IAAI,CAAC,SAAS;KAClB,CAAC,CAAC;IACH,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACpB,8EAA8E;IAC9E,KAAK,CAAC,uBAAuB,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;IAEpE,OAAO;QACL,IAAI;QAEJ,YAAY,CAAC,SAAS,EAAE,OAAO;YAC7B,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,YAAY,GAAG,CAAC,eAAe,CAAC,SAAS,CAAC,SAAS,EAAE,uBAAuB,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAChI,CAAC;QAED,iBAAiB,CAAC,SAAS;YACzB,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;gBAC5B,qEAAqE;gBACrE,MAAM,WAAW,GAAG,eAAe,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;gBAC5D,IAAI,WAAW,EAAE,CAAC;oBAChB,MAAM,CAAC,qBAAqB,CAAC,SAAS,EAAE,YAAY,GAAG,WAAW,CAAC,CAAC;gBACtE,CAAC;gBAED,2EAA2E;gBAC3E,IAAI,UAAU,GAAG,uBAAuB,CAAC;gBACzC,IAAI,GAAG,GAAG,eAAe,CAAC,SAAS,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;gBAC3D,OAAO,GAAG,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,qBAAqB,IAAI,UAAU,GAAG,GAAG,EAAE,CAAC;oBACzF,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;oBACxC,GAAG,GAAG,eAAe,CAAC,SAAS,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;gBACzD,CAAC;gBACD,IAAI,CAAC,GAAG;oBAAE,OAAO;gBACjB,IAAI,GAAG,KAAK,WAAW;oBAAE,OAAO;gBAChC,MAAM,CAAC,qBAAqB,CAAC,SAAS,EAAE,YAAY,GAAG,GAAG,CAAC,CAAC;YAC9D,CAAC,CAAC,CAAC;QACL,CAAC;QAED,KAAK,CAAC,IAAI;YACR,MAAM,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACrB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/terminal-pump.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { Session, SessionUsage } from './types.js';
|
|
|
5
5
|
export type SyntheticStopReason = 'complete' | 'error' | 'stopped';
|
|
6
6
|
export interface TerminalPumpDeps {
|
|
7
7
|
store: Pick<SessionStore, 'appendTerminalData' | 'loadSession' | 'saveSession' | 'loadTerminalLog'>;
|
|
8
|
-
terminalManager: Pick<TerminalManager, 'write' | 'destroy'
|
|
8
|
+
terminalManager: Pick<TerminalManager, 'write' | 'destroy'> & Partial<Pick<TerminalManager, 'whenParsed'>>;
|
|
9
9
|
publishTerminalData: (sessionId: string, data: string) => void;
|
|
10
10
|
publishSessionUpdate: (session: Session) => Promise<void>;
|
|
11
11
|
publishHookEvent: (sessionId: string, event: Record<string, unknown>) => Promise<void>;
|
|
@@ -17,30 +17,73 @@ export interface TerminalPumpDeps {
|
|
|
17
17
|
* previously persisted usage.
|
|
18
18
|
*/
|
|
19
19
|
collectUsage?: (session: Session) => Promise<SessionUsage | null>;
|
|
20
|
+
/**
|
|
21
|
+
* Whether anyone is receiving this session's live output right now (a direct
|
|
22
|
+
* peer or an unexpired remote watcher). Unwatched sessions coalesce output in
|
|
23
|
+
* a longer window. Whoever makes a session watched must call `flush` before
|
|
24
|
+
* producing the attach snapshot. Defaults to "always watched".
|
|
25
|
+
*/
|
|
26
|
+
isWatched?: (sessionId: string) => boolean;
|
|
20
27
|
/** Test seams; production uses the defaults. */
|
|
21
28
|
flushIntervalMs?: number;
|
|
22
29
|
maxBufferBytes?: number;
|
|
30
|
+
unwatchedFlushIntervalMs?: number;
|
|
31
|
+
unwatchedMaxBufferBytes?: number;
|
|
32
|
+
snapshotTimeoutMs?: number;
|
|
23
33
|
}
|
|
24
34
|
/**
|
|
25
35
|
* Terminal output pump: buffers runner PTY output per session (coalescing into
|
|
26
|
-
* ≤16ms / ≤32KB flushes to the store + transports
|
|
27
|
-
*
|
|
36
|
+
* ≤16ms / ≤32KB flushes to the store + transports while the session is watched,
|
|
37
|
+
* ≤250ms / ≤256KiB while nobody is), and owns the runner lifecycle handlers
|
|
38
|
+
* ('complete'/'error') that persist final session statuses. The live emulator
|
|
39
|
+
* (terminalManager) is fed immediately and never waits for a flush.
|
|
28
40
|
*/
|
|
29
41
|
export declare class TerminalPump {
|
|
30
42
|
private readonly deps;
|
|
31
|
-
private readonly
|
|
32
|
-
private readonly
|
|
43
|
+
private readonly pending;
|
|
44
|
+
private readonly pendingAppends;
|
|
45
|
+
private readonly snapshotHolds;
|
|
33
46
|
private readonly sessionWrites;
|
|
34
47
|
private readonly pendingAsync;
|
|
35
48
|
private track;
|
|
36
49
|
isIdle(): boolean;
|
|
37
50
|
private readonly flushIntervalMs;
|
|
38
51
|
private readonly maxBufferBytes;
|
|
52
|
+
private readonly unwatchedFlushIntervalMs;
|
|
53
|
+
private readonly unwatchedMaxBufferBytes;
|
|
54
|
+
private readonly snapshotTimeoutMs;
|
|
39
55
|
constructor(deps: TerminalPumpDeps);
|
|
40
56
|
/** Wire the pump onto the runner's data/lifecycle events. */
|
|
41
57
|
attach(runner: Pick<ProcessRunner, 'on'>): void;
|
|
42
58
|
handleData(sessionId: string, data: string): void;
|
|
59
|
+
/**
|
|
60
|
+
* Hand a session's pending output to the store and the transports now. Runs
|
|
61
|
+
* before terminal.log is read or cleared, on session exit and on shutdown.
|
|
62
|
+
* Screen snapshots go through `snapshot`, never a bare flush.
|
|
63
|
+
*/
|
|
43
64
|
flush(sessionId: string): void;
|
|
65
|
+
/**
|
|
66
|
+
* Produce a screen snapshot (attach replay, screen dump) at an exact cut in
|
|
67
|
+
* the output stream. Everything received so far is sent as output first;
|
|
68
|
+
* `produce` then runs once the emulator has parsed exactly those bytes, and
|
|
69
|
+
* output received in between is delivered only after it. A viewer that is
|
|
70
|
+
* reset by the snapshot therefore neither loses nor repeats a byte, whether
|
|
71
|
+
* it joined the stream before or after the cut. Concurrent snapshots of one
|
|
72
|
+
* session share a cut. `produce` runs synchronously only for a session that
|
|
73
|
+
* has no emulator (or a pump without one); otherwise it runs later, from the
|
|
74
|
+
* emulator's write loop.
|
|
75
|
+
*
|
|
76
|
+
* If the emulator has not caught up within the timeout (a very large
|
|
77
|
+
* backlog), the held output is released as plain output and NO snapshot is
|
|
78
|
+
* produced from that cut — a screen taken then could be missing bytes that
|
|
79
|
+
* were already sent. The producers stay queued; when the emulator finally
|
|
80
|
+
* reports, a new cut is taken for them. A snapshot is therefore late in that
|
|
81
|
+
* case, never inconsistent.
|
|
82
|
+
*/
|
|
83
|
+
snapshot(sessionId: string, produce: () => void): void;
|
|
84
|
+
private startSnapshot;
|
|
85
|
+
/** Flush every session and wait until the store has taken all of it (shutdown). */
|
|
86
|
+
drain(): Promise<void>;
|
|
44
87
|
withSessionWrite(sessionId: string, task: () => Promise<void>): Promise<void>;
|
|
45
88
|
publishSyntheticStop(sessionId: string, reason: SyntheticStopReason): void;
|
|
46
89
|
/**
|
package/dist/terminal-pump.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
const FLUSH_INTERVAL_MS = 16;
|
|
2
2
|
const MAX_BUFFER_BYTES = 32_000;
|
|
3
|
+
const UNWATCHED_FLUSH_INTERVAL_MS = 250;
|
|
4
|
+
const UNWATCHED_MAX_BUFFER_BYTES = 256 * 1024;
|
|
5
|
+
/** Upper bound on how long a snapshot may hold back a session's output. */
|
|
6
|
+
const SNAPSHOT_TIMEOUT_MS = 1000;
|
|
3
7
|
/** Raw terminal chars considered for the errorReason tail (pre-sanitize). */
|
|
4
8
|
const ERROR_TAIL_RAW_CHARS = 1200;
|
|
5
9
|
/** Max sanitized tail chars kept in errorReason. */
|
|
@@ -17,13 +21,16 @@ function sanitizeTerminalTail(raw) {
|
|
|
17
21
|
}
|
|
18
22
|
/**
|
|
19
23
|
* Terminal output pump: buffers runner PTY output per session (coalescing into
|
|
20
|
-
* ≤16ms / ≤32KB flushes to the store + transports
|
|
21
|
-
*
|
|
24
|
+
* ≤16ms / ≤32KB flushes to the store + transports while the session is watched,
|
|
25
|
+
* ≤250ms / ≤256KiB while nobody is), and owns the runner lifecycle handlers
|
|
26
|
+
* ('complete'/'error') that persist final session statuses. The live emulator
|
|
27
|
+
* (terminalManager) is fed immediately and never waits for a flush.
|
|
22
28
|
*/
|
|
23
29
|
export class TerminalPump {
|
|
24
30
|
deps;
|
|
25
|
-
|
|
26
|
-
|
|
31
|
+
pending = new Map();
|
|
32
|
+
pendingAppends = new Set();
|
|
33
|
+
snapshotHolds = new Map();
|
|
27
34
|
// Per-session write queue so concurrent load/modify/save flows (hooks,
|
|
28
35
|
// runner exit handlers, stop_session) cannot interleave and resurrect a
|
|
29
36
|
// stale status.
|
|
@@ -35,14 +42,20 @@ export class TerminalPump {
|
|
|
35
42
|
return work;
|
|
36
43
|
}
|
|
37
44
|
isIdle() {
|
|
38
|
-
return this.
|
|
45
|
+
return this.pending.size === 0 && this.sessionWrites.size === 0 && this.pendingAsync.size === 0;
|
|
39
46
|
}
|
|
40
47
|
flushIntervalMs;
|
|
41
48
|
maxBufferBytes;
|
|
49
|
+
unwatchedFlushIntervalMs;
|
|
50
|
+
unwatchedMaxBufferBytes;
|
|
51
|
+
snapshotTimeoutMs;
|
|
42
52
|
constructor(deps) {
|
|
43
53
|
this.deps = deps;
|
|
44
54
|
this.flushIntervalMs = deps.flushIntervalMs ?? FLUSH_INTERVAL_MS;
|
|
45
55
|
this.maxBufferBytes = deps.maxBufferBytes ?? MAX_BUFFER_BYTES;
|
|
56
|
+
this.unwatchedFlushIntervalMs = deps.unwatchedFlushIntervalMs ?? UNWATCHED_FLUSH_INTERVAL_MS;
|
|
57
|
+
this.unwatchedMaxBufferBytes = deps.unwatchedMaxBufferBytes ?? UNWATCHED_MAX_BUFFER_BYTES;
|
|
58
|
+
this.snapshotTimeoutMs = deps.snapshotTimeoutMs ?? SNAPSHOT_TIMEOUT_MS;
|
|
46
59
|
}
|
|
47
60
|
/** Wire the pump onto the runner's data/lifecycle events. */
|
|
48
61
|
attach(runner) {
|
|
@@ -52,28 +65,138 @@ export class TerminalPump {
|
|
|
52
65
|
}
|
|
53
66
|
handleData(sessionId, data) {
|
|
54
67
|
this.deps.terminalManager.write(sessionId, data);
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
68
|
+
let pending = this.pending.get(sessionId);
|
|
69
|
+
if (!pending) {
|
|
70
|
+
pending = { data: '', bytes: 0, unwatchedTimer: false };
|
|
71
|
+
this.pending.set(sessionId, pending);
|
|
72
|
+
}
|
|
73
|
+
pending.data += data;
|
|
74
|
+
pending.bytes += Buffer.byteLength(data, 'utf-8');
|
|
75
|
+
// A viewer waiting for its snapshot is not attached yet but is watching.
|
|
76
|
+
if (this.snapshotHolds.has(sessionId) || (this.deps.isWatched?.(sessionId) ?? true)) {
|
|
77
|
+
// A buffer still riding the long window means a watcher appeared without
|
|
78
|
+
// an explicit flush: deliver now instead of making it wait.
|
|
79
|
+
if (pending.data.length >= this.maxBufferBytes || pending.unwatchedTimer) {
|
|
80
|
+
this.flush(sessionId);
|
|
81
|
+
}
|
|
82
|
+
else if (!pending.timer) {
|
|
83
|
+
pending.timer = setTimeout(() => this.flush(sessionId), this.flushIntervalMs);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
else if (pending.bytes > this.unwatchedMaxBufferBytes) {
|
|
58
87
|
this.flush(sessionId);
|
|
59
88
|
}
|
|
60
|
-
else if (!
|
|
61
|
-
|
|
89
|
+
else if (!pending.timer) {
|
|
90
|
+
pending.timer = setTimeout(() => this.flush(sessionId), this.unwatchedFlushIntervalMs);
|
|
91
|
+
pending.unwatchedTimer = true;
|
|
62
92
|
}
|
|
63
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Hand a session's pending output to the store and the transports now. Runs
|
|
96
|
+
* before terminal.log is read or cleared, on session exit and on shutdown.
|
|
97
|
+
* Screen snapshots go through `snapshot`, never a bare flush.
|
|
98
|
+
*/
|
|
64
99
|
flush(sessionId) {
|
|
65
|
-
const
|
|
66
|
-
if (!
|
|
100
|
+
const pending = this.pending.get(sessionId);
|
|
101
|
+
if (!pending)
|
|
67
102
|
return;
|
|
68
|
-
this.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
this.flushTimers.delete(sessionId);
|
|
73
|
-
this.track(this.deps.store.appendTerminalData(sessionId, buf)).catch((err) => {
|
|
103
|
+
this.pending.delete(sessionId);
|
|
104
|
+
if (pending.timer)
|
|
105
|
+
clearTimeout(pending.timer);
|
|
106
|
+
const append = this.track(this.deps.store.appendTerminalData(sessionId, pending.data)).catch((err) => {
|
|
74
107
|
console.error(`[Bridge] Failed to store terminal data for ${sessionId}:`, err);
|
|
75
108
|
});
|
|
76
|
-
this.
|
|
109
|
+
this.pendingAppends.add(append);
|
|
110
|
+
void append.then(() => this.pendingAppends.delete(append));
|
|
111
|
+
const hold = this.snapshotHolds.get(sessionId);
|
|
112
|
+
if (hold)
|
|
113
|
+
hold.deferred.push(pending.data);
|
|
114
|
+
else
|
|
115
|
+
this.deps.publishTerminalData(sessionId, pending.data);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Produce a screen snapshot (attach replay, screen dump) at an exact cut in
|
|
119
|
+
* the output stream. Everything received so far is sent as output first;
|
|
120
|
+
* `produce` then runs once the emulator has parsed exactly those bytes, and
|
|
121
|
+
* output received in between is delivered only after it. A viewer that is
|
|
122
|
+
* reset by the snapshot therefore neither loses nor repeats a byte, whether
|
|
123
|
+
* it joined the stream before or after the cut. Concurrent snapshots of one
|
|
124
|
+
* session share a cut. `produce` runs synchronously only for a session that
|
|
125
|
+
* has no emulator (or a pump without one); otherwise it runs later, from the
|
|
126
|
+
* emulator's write loop.
|
|
127
|
+
*
|
|
128
|
+
* If the emulator has not caught up within the timeout (a very large
|
|
129
|
+
* backlog), the held output is released as plain output and NO snapshot is
|
|
130
|
+
* produced from that cut — a screen taken then could be missing bytes that
|
|
131
|
+
* were already sent. The producers stay queued; when the emulator finally
|
|
132
|
+
* reports, a new cut is taken for them. A snapshot is therefore late in that
|
|
133
|
+
* case, never inconsistent.
|
|
134
|
+
*/
|
|
135
|
+
snapshot(sessionId, produce) {
|
|
136
|
+
const active = this.snapshotHolds.get(sessionId);
|
|
137
|
+
if (active)
|
|
138
|
+
active.producers.push(produce);
|
|
139
|
+
else
|
|
140
|
+
this.startSnapshot(sessionId, [produce]);
|
|
141
|
+
}
|
|
142
|
+
startSnapshot(sessionId, producers) {
|
|
143
|
+
this.flush(sessionId);
|
|
144
|
+
const hold = { producers, deferred: [] };
|
|
145
|
+
this.snapshotHolds.set(sessionId, hold);
|
|
146
|
+
let timer;
|
|
147
|
+
const release = () => {
|
|
148
|
+
this.snapshotHolds.delete(sessionId);
|
|
149
|
+
for (const data of hold.deferred)
|
|
150
|
+
this.deps.publishTerminalData(sessionId, data);
|
|
151
|
+
// Output that arrived during the hold follows at once, not a window later.
|
|
152
|
+
this.flush(sessionId);
|
|
153
|
+
};
|
|
154
|
+
const onParsed = () => {
|
|
155
|
+
if (timer)
|
|
156
|
+
clearTimeout(timer);
|
|
157
|
+
if (this.snapshotHolds.get(sessionId) !== hold) {
|
|
158
|
+
// Timed out earlier and its output has moved on: cut again.
|
|
159
|
+
const current = this.snapshotHolds.get(sessionId);
|
|
160
|
+
if (current)
|
|
161
|
+
current.producers.push(...hold.producers);
|
|
162
|
+
else
|
|
163
|
+
this.startSnapshot(sessionId, hold.producers);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
try {
|
|
167
|
+
for (const run of hold.producers) {
|
|
168
|
+
try {
|
|
169
|
+
run();
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
console.error(`[Bridge] Failed to produce terminal snapshot for ${sessionId}:`, err);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
finally {
|
|
177
|
+
release();
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
const whenParsed = this.deps.terminalManager.whenParsed;
|
|
181
|
+
if (!whenParsed) {
|
|
182
|
+
onParsed();
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
// Output must never stay held because an emulator is slow to report back.
|
|
186
|
+
timer = setTimeout(() => {
|
|
187
|
+
if (this.snapshotHolds.get(sessionId) === hold)
|
|
188
|
+
release();
|
|
189
|
+
}, this.snapshotTimeoutMs);
|
|
190
|
+
timer.unref?.();
|
|
191
|
+
whenParsed.call(this.deps.terminalManager, sessionId, onParsed);
|
|
192
|
+
}
|
|
193
|
+
/** Flush every session and wait until the store has taken all of it (shutdown). */
|
|
194
|
+
async drain() {
|
|
195
|
+
for (const sessionId of [...this.pending.keys()])
|
|
196
|
+
this.flush(sessionId);
|
|
197
|
+
while (this.pendingAppends.size > 0) {
|
|
198
|
+
await Promise.all([...this.pendingAppends]);
|
|
199
|
+
}
|
|
77
200
|
}
|
|
78
201
|
withSessionWrite(sessionId, task) {
|
|
79
202
|
const prev = this.sessionWrites.get(sessionId) ?? Promise.resolve();
|
|
@@ -176,7 +299,7 @@ export class TerminalPump {
|
|
|
176
299
|
handleError(sessionId, error) {
|
|
177
300
|
// Capture what's still buffered BEFORE flush drains it — the errorReason
|
|
178
301
|
// tail needs it if the (unawaited) flush append hasn't hit the store yet.
|
|
179
|
-
const pendingAtError = this.
|
|
302
|
+
const pendingAtError = this.pending.get(sessionId)?.data ?? '';
|
|
180
303
|
this.flush(sessionId);
|
|
181
304
|
this.publishSyntheticStop(sessionId, 'error');
|
|
182
305
|
void this.track(this.withSessionWrite(sessionId, async () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal-pump.js","sourceRoot":"","sources":["../src/terminal-pump.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"terminal-pump.js","sourceRoot":"","sources":["../src/terminal-pump.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -90,7 +90,7 @@ export interface Command {
|
|
|
90
90
|
payload: CommandPayload;
|
|
91
91
|
requestId: string;
|
|
92
92
|
}
|
|
93
|
-
export type CommandType = 'get_pull_request_review' | 'get_pull_request_review_chunk' | 'preview_chat_list' | 'preview_chat_send' | 'preview_chat_reply' | 'get_pull_request_statuses' | 'session_preview_status' | 'session_preview_chunk' | 'get_bridge_update' | 'update_bridge' | 'security_devices' | 'security_invite' | 'security_revoke' | 'create_session' | 'stop_session' | 'list_sessions' | 'get_history' | 'retry_session' | 'send_message' | 'rename_session' | 'remove_session' | 'bridge_exec' | 'clear_terminal' | 'update_session_parent' | 'get_session_usage' | 'get_sessions_usage' | 'get_session_attention' | 'resolve_session_attention' | 'answer_session_attention';
|
|
93
|
+
export type CommandType = 'get_pull_request_review' | 'get_pull_request_review_chunk' | 'preview_chat_list' | 'preview_chat_send' | 'preview_chat_reply' | 'get_pull_request_statuses' | 'session_preview_status' | 'session_preview_chunk' | 'get_bridge_update' | 'update_bridge' | 'security_devices' | 'security_invite' | 'security_revoke' | 'ledger_head' | 'ledger_chain' | 'create_session' | 'stop_session' | 'list_sessions' | 'get_history' | 'retry_session' | 'send_message' | 'rename_session' | 'remove_session' | 'bridge_exec' | 'clear_terminal' | 'update_session_parent' | 'get_session_usage' | 'get_sessions_usage' | 'get_session_attention' | 'resolve_session_attention' | 'answer_session_attention';
|
|
94
94
|
export interface GetSessionAttentionPayload {
|
|
95
95
|
bridgeId: string;
|
|
96
96
|
sessionId: string;
|
package/opencode-plugin/ftown.js
CHANGED
|
@@ -85,6 +85,7 @@ export function registerFtownOpencodePlugin(client, options = {}) {
|
|
|
85
85
|
let polling = false;
|
|
86
86
|
let inflight = false;
|
|
87
87
|
let seen = new Set();
|
|
88
|
+
const postedPromptIds = new Set();
|
|
88
89
|
let retryAt = 0;
|
|
89
90
|
let retryDelay = 5_000;
|
|
90
91
|
|
|
@@ -145,6 +146,8 @@ export function registerFtownOpencodePlugin(client, options = {}) {
|
|
|
145
146
|
inflight = true;
|
|
146
147
|
for (const messageId of ids) seen.add(messageId);
|
|
147
148
|
try {
|
|
149
|
+
// Tell the bridge first so the wake's no-text prompt hook is one-shot injected.
|
|
150
|
+
await postHook('FtownWakeSubmitted');
|
|
148
151
|
const result = await client.session.prompt({ path: { id }, body: {
|
|
149
152
|
parts: [{ type: 'text', text: `[ftown mail] ${MAIL_WAKE_TEXT}` }],
|
|
150
153
|
} });
|
|
@@ -229,9 +232,19 @@ export function registerFtownOpencodePlugin(client, options = {}) {
|
|
|
229
232
|
await postHook('SessionStart');
|
|
230
233
|
await poll();
|
|
231
234
|
break;
|
|
232
|
-
case 'message.updated':
|
|
233
|
-
|
|
235
|
+
case 'message.updated': {
|
|
236
|
+
const info = event.properties?.info;
|
|
237
|
+
if (info?.role === 'user') {
|
|
238
|
+
busy = true;
|
|
239
|
+
const messageId = info?.id;
|
|
240
|
+
if (typeof messageId === 'string' && messageId) {
|
|
241
|
+
if (postedPromptIds.has(messageId)) break;
|
|
242
|
+
postedPromptIds.add(messageId);
|
|
243
|
+
}
|
|
244
|
+
await postHook('UserPromptSubmit');
|
|
245
|
+
}
|
|
234
246
|
break;
|
|
247
|
+
}
|
|
235
248
|
case 'session.status':
|
|
236
249
|
if (event.properties?.status?.type === 'busy') { busy = true; await postHook('PreToolUse'); break; }
|
|
237
250
|
if (event.properties?.status?.type !== 'idle') break;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ftown",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.25.0",
|
|
4
4
|
"description": "CLI bridge for ftown — generic PTY-over-Centrifugo relay",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -72,5 +72,5 @@
|
|
|
72
72
|
"overrides": {
|
|
73
73
|
"qs": "6.16.1"
|
|
74
74
|
},
|
|
75
|
-
"gitHead": "
|
|
75
|
+
"gitHead": "e4010193f960ffff69015be86c5e06aa18dc060c"
|
|
76
76
|
}
|
package/skills/ftown/SKILL.md
CHANGED
|
@@ -45,7 +45,9 @@ ftown sessions attention --title "Pick a database" --message "Which database sho
|
|
|
45
45
|
ftown sessions attention-status <event-id> --wait
|
|
46
46
|
ftown sessions pr https://github.com/owner/repo/pull/123
|
|
47
47
|
ftown sessions pr --clear
|
|
48
|
-
ftown sessions preview ./preview.html
|
|
48
|
+
ftown sessions preview ./preview.html ./notes.md
|
|
49
|
+
ftown sessions preview --add ./extra.html
|
|
50
|
+
ftown sessions preview --remove notes.md
|
|
49
51
|
ftown sessions preview --clear
|
|
50
52
|
ftown sessions preview-reply --message "The preview is ready."
|
|
51
53
|
ftown harness mail send <session-id> --type task "review the API client"
|
|
@@ -59,12 +61,21 @@ Read `references/sessions.md` for the session, mail and terminal command
|
|
|
59
61
|
reference. Read `references/orchestrator.md` for practical worker coordination
|
|
60
62
|
examples. Each command group also has `--help`.
|
|
61
63
|
|
|
62
|
-
`ftown sessions preview <path
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
`--
|
|
67
|
-
|
|
64
|
+
`ftown sessions preview <path...>` registers up to 12 files in the current
|
|
65
|
+
session's working directory for the dashboard, in this order. Kind is by
|
|
66
|
+
extension: `.html`/`.htm` → HTML, `.md`/`.markdown` → Markdown, anything else
|
|
67
|
+
is rejected. Each file is at most 1 MiB. A duplicate basename is rejected.
|
|
68
|
+
`--add <path...>` appends to the current set, `--remove <name...>` removes by
|
|
69
|
+
basename, and `--clear` removes the whole registration (never deletes files).
|
|
70
|
+
HTML previews are self-contained: inline CSS and scripts and data images work;
|
|
71
|
+
sibling assets and network access are unsupported. Markdown is rendered as a
|
|
72
|
+
readable document with GFM (tables, task lists, fenced code) in the same
|
|
73
|
+
sandbox iframe, with no network and only `data:` images; raw HTML inside the
|
|
74
|
+
markdown is isolated the same way. With two or more registered files, the
|
|
75
|
+
dashboard shows a selector in the preview toolbar; a relative link between
|
|
76
|
+
registered files switches the selector. Publish updates by writing a temporary
|
|
77
|
+
file and atomically renaming it into place. Use `--session-id <id>` for an
|
|
78
|
+
explicit target.
|
|
68
79
|
|
|
69
80
|
Messages from the preview conversation arrive as ftown mail. Respond explicitly
|
|
70
81
|
with `ftown sessions preview-reply --message "Your response"`; use
|