@fnndsc/calypso 0.6.0 → 0.7.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/calypso.js +53 -3
- package/dist/calypso.js.map +1 -1
- package/dist/daemon/attachFile.d.ts +43 -0
- package/dist/daemon/attachFile.js +80 -0
- package/dist/daemon/attachFile.js.map +1 -0
- package/dist/daemon/engine.d.ts +16 -0
- package/dist/daemon/face.d.ts +127 -0
- package/dist/daemon/face.js +419 -0
- package/dist/daemon/face.js.map +1 -0
- package/dist/daemon/launch.d.ts +21 -6
- package/dist/daemon/launch.js +82 -18
- package/dist/daemon/launch.js.map +1 -1
- package/dist/daemon/server.d.ts +83 -4
- package/dist/daemon/server.js +157 -5
- package/dist/daemon/server.js.map +1 -1
- package/dist/daemon/static.d.ts +13 -0
- package/dist/daemon/static.js +36 -0
- package/dist/daemon/static.js.map +1 -1
- package/dist/index.d.ts +15 -8
- package/dist/index.js +14 -7
- package/dist/index.js.map +1 -1
- package/package.json +6 -9
- package/dist/protocol/envelope.d.ts +0 -136
- package/dist/protocol/envelope.js +0 -46
- package/dist/protocol/envelope.js.map +0 -1
- package/dist/protocol/index.d.ts +0 -16
- package/dist/protocol/index.js +0 -17
- package/dist/protocol/index.js.map +0 -1
- package/dist/protocol/messages.d.ts +0 -1568
- package/dist/protocol/messages.js +0 -281
- package/dist/protocol/messages.js.map +0 -1
- package/dist/protocol/validate.d.ts +0 -57
- package/dist/protocol/validate.js +0 -88
- package/dist/protocol/validate.js.map +0 -1
- package/dist/protocol/version.d.ts +0 -25
- package/dist/protocol/version.js +0 -28
- package/dist/protocol/version.js.map +0 -1
package/dist/calypso.js
CHANGED
|
@@ -12,8 +12,11 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { fileURLToPath } from 'node:url';
|
|
14
14
|
import { realpathSync } from 'node:fs';
|
|
15
|
-
import { engine_create, sessionConnect_fromSaved } from '@fnndsc/brasa';
|
|
15
|
+
import { engine_create, procIndex_snapshot, sessionConnect_fromSaved } from '@fnndsc/brasa';
|
|
16
|
+
import chalk from 'chalk';
|
|
16
17
|
import { daemon_launch } from './daemon/launch.js';
|
|
18
|
+
import { face_start } from './daemon/face.js';
|
|
19
|
+
import { LocalBerthResolver, berthUrl_isAlive } from './daemon/berth.js';
|
|
17
20
|
/**
|
|
18
21
|
* Creates the engine, restores the saved session, and hosts the daemon.
|
|
19
22
|
*
|
|
@@ -29,7 +32,52 @@ async function calypso_start() {
|
|
|
29
32
|
else {
|
|
30
33
|
console.error(`[!] No active session (${result.status}). Log in with 'chell' first; hosting offline.`);
|
|
31
34
|
}
|
|
32
|
-
await daemon_launch(engine);
|
|
35
|
+
const info = await daemon_launch(engine);
|
|
36
|
+
// On a TTY, the terminal's resting state is the console face; off one
|
|
37
|
+
// (systemd, nohup) face_start declines and logging stays sequential.
|
|
38
|
+
face_start({
|
|
39
|
+
info: [
|
|
40
|
+
{ label: 'identity', value: info.identity },
|
|
41
|
+
{ label: 'wire', value: info.url },
|
|
42
|
+
...(info.argusUrl !== null ? [{ label: 'ARGUS', value: info.argusUrl }] : []),
|
|
43
|
+
{ label: 'token', value: info.token },
|
|
44
|
+
{ label: 'berth', value: info.berthPath },
|
|
45
|
+
{ label: 'attach', value: `chell --remote --attach ${info.url} --token ${info.token}` },
|
|
46
|
+
],
|
|
47
|
+
telemetry_get: () => {
|
|
48
|
+
const index = procIndex_snapshot();
|
|
49
|
+
return {
|
|
50
|
+
sessions: info.daemon.surfaces_count(),
|
|
51
|
+
busy: info.daemon.busy_get(),
|
|
52
|
+
jobs: index.jobs,
|
|
53
|
+
feeds: index.feeds,
|
|
54
|
+
};
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Prints how to attach to each live daemon.
|
|
60
|
+
*
|
|
61
|
+
* A daemon prints its addresses once, at launch, into a terminal it then
|
|
62
|
+
* occupies. The facts survive in the berth — url and token, mode 0600 in the
|
|
63
|
+
* user's runtime directory — so they are reprinted from there rather than
|
|
64
|
+
* copied somewhere more convenient and less private. `/tmp` would be more
|
|
65
|
+
* convenient; it is also world-readable, and the token is a credential.
|
|
66
|
+
*/
|
|
67
|
+
async function berths_print() {
|
|
68
|
+
const resolver = new LocalBerthResolver((berth) => berthUrl_isAlive(berth.url));
|
|
69
|
+
const berths = await resolver.list();
|
|
70
|
+
if (berths.length === 0) {
|
|
71
|
+
console.error(chalk.yellow('No CALYPSO daemon is running.'));
|
|
72
|
+
console.error(chalk.gray("Start one with: chell --daemon <user>@<url>"));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
for (const berth of berths) {
|
|
76
|
+
const web = berth.url.replace(/^ws/, 'http');
|
|
77
|
+
console.log(chalk.bold.cyan(berth.identity));
|
|
78
|
+
console.log(chalk.green(` ARGUS: ${web}/?token=${berth.token}`));
|
|
79
|
+
console.log(chalk.gray(` attach: chell --remote --attach ${berth.url} --token ${berth.token}`));
|
|
80
|
+
}
|
|
33
81
|
}
|
|
34
82
|
const currentFile = fileURLToPath(import.meta.url);
|
|
35
83
|
let isMain = false;
|
|
@@ -40,6 +88,8 @@ catch {
|
|
|
40
88
|
// Not invoked as a script.
|
|
41
89
|
}
|
|
42
90
|
if (isMain) {
|
|
43
|
-
|
|
91
|
+
// One flag, not a subcommand grammar: this binary hosts a daemon, and the
|
|
92
|
+
// only other thing anyone needs from it is where the running ones are.
|
|
93
|
+
void (process.argv.includes('--berths') ? berths_print() : calypso_start());
|
|
44
94
|
}
|
|
45
95
|
//# sourceMappingURL=calypso.js.map
|
package/dist/calypso.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calypso.js","sourceRoot":"","sources":["../src/calypso.ts"],"names":[],"mappings":";AACA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAA6C,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"calypso.js","sourceRoot":"","sources":["../src/calypso.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file The attach note: a daemon's addresses, written where they can be read.
|
|
3
|
+
*
|
|
4
|
+
* A daemon prints its ARGUS link and attach command once, into a terminal it
|
|
5
|
+
* then occupies with a live boot animation. Selecting text out from under a
|
|
6
|
+
* repainting screen is awkward, and scrollback is lost the moment anyone
|
|
7
|
+
* clears it — so the same lines are also written to a file.
|
|
8
|
+
*
|
|
9
|
+
* The file carries the attach token, which is a credential, and `/tmp` is
|
|
10
|
+
* world-readable. Three things follow, and none is optional:
|
|
11
|
+
*
|
|
12
|
+
* * it is created `0600`, so the mode rather than the directory protects it;
|
|
13
|
+
* * it is created exclusively (`wx`), so a symlink planted at the path by
|
|
14
|
+
* another user makes the write fail rather than land somewhere chosen by
|
|
15
|
+
* them; and
|
|
16
|
+
* * it is removed when the daemon exits, so a dead session's token does not
|
|
17
|
+
* linger.
|
|
18
|
+
*
|
|
19
|
+
* `calypso --berths` reads the same facts from the berth, which is `0600` in
|
|
20
|
+
* the user's own runtime directory. That remains the safer route; this one is
|
|
21
|
+
* the convenient one.
|
|
22
|
+
*
|
|
23
|
+
* @module
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* The path this daemon's attach note occupies.
|
|
27
|
+
*
|
|
28
|
+
* Per OS user rather than per session, so it can be named in a message and
|
|
29
|
+
* found again without reading one. A second daemon for a second CUBE identity
|
|
30
|
+
* overwrites it; `calypso --berths` lists them all.
|
|
31
|
+
*
|
|
32
|
+
* @returns An absolute path in the system temporary directory.
|
|
33
|
+
*/
|
|
34
|
+
export declare function attachFile_path(): string;
|
|
35
|
+
/**
|
|
36
|
+
* Writes the attach note, replacing any note this user left before.
|
|
37
|
+
*
|
|
38
|
+
* @param lines - The addresses to record, one per line.
|
|
39
|
+
* @returns The path written, or null when it could not be written safely.
|
|
40
|
+
*/
|
|
41
|
+
export declare function attachFile_write(lines: string[]): string | null;
|
|
42
|
+
/** Removes the attach note, so a dead session's token does not linger. */
|
|
43
|
+
export declare function attachFile_remove(): void;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file The attach note: a daemon's addresses, written where they can be read.
|
|
3
|
+
*
|
|
4
|
+
* A daemon prints its ARGUS link and attach command once, into a terminal it
|
|
5
|
+
* then occupies with a live boot animation. Selecting text out from under a
|
|
6
|
+
* repainting screen is awkward, and scrollback is lost the moment anyone
|
|
7
|
+
* clears it — so the same lines are also written to a file.
|
|
8
|
+
*
|
|
9
|
+
* The file carries the attach token, which is a credential, and `/tmp` is
|
|
10
|
+
* world-readable. Three things follow, and none is optional:
|
|
11
|
+
*
|
|
12
|
+
* * it is created `0600`, so the mode rather than the directory protects it;
|
|
13
|
+
* * it is created exclusively (`wx`), so a symlink planted at the path by
|
|
14
|
+
* another user makes the write fail rather than land somewhere chosen by
|
|
15
|
+
* them; and
|
|
16
|
+
* * it is removed when the daemon exits, so a dead session's token does not
|
|
17
|
+
* linger.
|
|
18
|
+
*
|
|
19
|
+
* `calypso --berths` reads the same facts from the berth, which is `0600` in
|
|
20
|
+
* the user's own runtime directory. That remains the safer route; this one is
|
|
21
|
+
* the convenient one.
|
|
22
|
+
*
|
|
23
|
+
* @module
|
|
24
|
+
*/
|
|
25
|
+
import { chmodSync, openSync, writeSync, closeSync, rmSync } from 'node:fs';
|
|
26
|
+
import { tmpdir } from 'node:os';
|
|
27
|
+
import { join } from 'node:path';
|
|
28
|
+
import { userInfo } from 'node:os';
|
|
29
|
+
/**
|
|
30
|
+
* The path this daemon's attach note occupies.
|
|
31
|
+
*
|
|
32
|
+
* Per OS user rather than per session, so it can be named in a message and
|
|
33
|
+
* found again without reading one. A second daemon for a second CUBE identity
|
|
34
|
+
* overwrites it; `calypso --berths` lists them all.
|
|
35
|
+
*
|
|
36
|
+
* @returns An absolute path in the system temporary directory.
|
|
37
|
+
*/
|
|
38
|
+
export function attachFile_path() {
|
|
39
|
+
return join(tmpdir(), `calypso-${userInfo().username}.attach`);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Writes the attach note, replacing any note this user left before.
|
|
43
|
+
*
|
|
44
|
+
* @param lines - The addresses to record, one per line.
|
|
45
|
+
* @returns The path written, or null when it could not be written safely.
|
|
46
|
+
*/
|
|
47
|
+
export function attachFile_write(lines) {
|
|
48
|
+
const path = attachFile_path();
|
|
49
|
+
try {
|
|
50
|
+
// Remove our own stale note first, then create exclusively: if anything
|
|
51
|
+
// reappears at the path in between, the create fails rather than writing
|
|
52
|
+
// through whatever is there.
|
|
53
|
+
rmSync(path, { force: true });
|
|
54
|
+
const handle = openSync(path, 'wx', 0o600);
|
|
55
|
+
try {
|
|
56
|
+
writeSync(handle, `${lines.join('\n')}\n`);
|
|
57
|
+
}
|
|
58
|
+
finally {
|
|
59
|
+
closeSync(handle);
|
|
60
|
+
}
|
|
61
|
+
// openSync's mode is subject to umask; set it outright.
|
|
62
|
+
chmodSync(path, 0o600);
|
|
63
|
+
return path;
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// A note is a convenience. Failing to write one must never stop a daemon
|
|
67
|
+
// from starting, and the addresses were printed regardless.
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/** Removes the attach note, so a dead session's token does not linger. */
|
|
72
|
+
export function attachFile_remove() {
|
|
73
|
+
try {
|
|
74
|
+
rmSync(attachFile_path(), { force: true });
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// Nothing useful to say at exit about a file that may already be gone.
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=attachFile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachFile.js","sourceRoot":"","sources":["../../src/daemon/attachFile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC5E,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe;IAC7B,OAAO,IAAI,CAAC,MAAM,EAAE,EAAE,WAAW,QAAQ,EAAE,CAAC,QAAQ,SAAS,CAAC,CAAC;AACjE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAe;IAC9C,MAAM,IAAI,GAAW,eAAe,EAAE,CAAC;IACvC,IAAI,CAAC;QACH,wEAAwE;QACxE,yEAAyE;QACzE,6BAA6B;QAC7B,MAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9B,MAAM,MAAM,GAAW,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QACnD,IAAI,CAAC;YACH,SAAS,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7C,CAAC;gBAAS,CAAC;YACT,SAAS,CAAC,MAAM,CAAC,CAAC;QACpB,CAAC;QACD,wDAAwD;QACxD,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,yEAAyE;QACzE,4DAA4D;QAC5D,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,iBAAiB;IAC/B,IAAI,CAAC;QACH,MAAM,CAAC,eAAe,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,uEAAuE;IACzE,CAAC;AACH,CAAC"}
|
package/dist/daemon/engine.d.ts
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* @module
|
|
12
12
|
*/
|
|
13
13
|
import type { CommandEnvelope } from '@fnndsc/cumin';
|
|
14
|
+
import type { Regard } from '@fnndsc/menu';
|
|
14
15
|
/**
|
|
15
16
|
* A completion answer: the candidates and the prefix they complete.
|
|
16
17
|
*
|
|
@@ -58,4 +59,19 @@ export interface HostedEngine {
|
|
|
58
59
|
* @returns The file's bytes.
|
|
59
60
|
*/
|
|
60
61
|
file_read?(filePath: string): Promise<Buffer>;
|
|
62
|
+
/**
|
|
63
|
+
* Notes a regard write relayed from a surface, retaining it as session
|
|
64
|
+
* truth engine-side. Optional: a daemon still retains and rebroadcasts
|
|
65
|
+
* regard on the wire without it.
|
|
66
|
+
*
|
|
67
|
+
* @param regard - The indicated address with its provenance.
|
|
68
|
+
*/
|
|
69
|
+
regard_note?(regard: Regard): void;
|
|
70
|
+
/**
|
|
71
|
+
* Returns the engine's retained regard, or null before the first
|
|
72
|
+
* indication.
|
|
73
|
+
*
|
|
74
|
+
* @returns The retained regard, or null.
|
|
75
|
+
*/
|
|
76
|
+
regard_get?(): Regard | null;
|
|
61
77
|
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/** One labeled fact shown on the face's identity panel. */
|
|
2
|
+
export interface FaceInfo {
|
|
3
|
+
label: string;
|
|
4
|
+
value: string;
|
|
5
|
+
}
|
|
6
|
+
/** Live daemon readings the face polls once per frame. */
|
|
7
|
+
export interface FaceTelemetry {
|
|
8
|
+
/** Attached surfaces right now. */
|
|
9
|
+
sessions: number;
|
|
10
|
+
/** Whether a foreground command is executing. */
|
|
11
|
+
busy: boolean;
|
|
12
|
+
/** Jobs the proc index holds. */
|
|
13
|
+
jobs: number;
|
|
14
|
+
/** Feeds the proc index holds. */
|
|
15
|
+
feeds: number;
|
|
16
|
+
}
|
|
17
|
+
/** What the face needs from its host. */
|
|
18
|
+
export interface FaceOptions {
|
|
19
|
+
/** Identity panel rows: identity, wire, web surface, token, berth. */
|
|
20
|
+
info: FaceInfo[];
|
|
21
|
+
/** Live readings; omitted readings render as an idle daemon. */
|
|
22
|
+
telemetry_get?: () => FaceTelemetry;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* A bounded line buffer for output arriving while the face owns the screen.
|
|
26
|
+
*
|
|
27
|
+
* Everything a stray `console.log` (a retry warning, a background sweep
|
|
28
|
+
* report) writes is caged here: the newest lines feed the face's strip, and
|
|
29
|
+
* the whole run since the last flush is replayed into the normal buffer when
|
|
30
|
+
* the operator drops to text — so nothing is ever lost, only re-homed.
|
|
31
|
+
*/
|
|
32
|
+
export declare class FaceLogRing {
|
|
33
|
+
private lines;
|
|
34
|
+
private pending;
|
|
35
|
+
private unflushed;
|
|
36
|
+
/**
|
|
37
|
+
* Absorbs one raw write, splitting it into stripped, stored lines.
|
|
38
|
+
*
|
|
39
|
+
* A carriage return without a newline is a redraw (a spinner frame): it
|
|
40
|
+
* discards what preceded it on the line rather than appending, so a
|
|
41
|
+
* thousand frames stay one line, not one enormous one.
|
|
42
|
+
*
|
|
43
|
+
* @param chunk - The text a hijacked stdout/stderr write carried.
|
|
44
|
+
*/
|
|
45
|
+
push(chunk: string): void;
|
|
46
|
+
/**
|
|
47
|
+
* The newest lines, for the face's log strip.
|
|
48
|
+
*
|
|
49
|
+
* @param count - How many lines the strip shows.
|
|
50
|
+
* @returns Up to `count` lines, oldest first.
|
|
51
|
+
*/
|
|
52
|
+
tail(count: number): string[];
|
|
53
|
+
/**
|
|
54
|
+
* Returns and forgets the lines not yet replayed into the normal buffer.
|
|
55
|
+
*
|
|
56
|
+
* @returns The unflushed lines, oldest first.
|
|
57
|
+
*/
|
|
58
|
+
drain(): string[];
|
|
59
|
+
}
|
|
60
|
+
/** Everything the pure composer needs to draw one frame. */
|
|
61
|
+
export interface FaceFrame {
|
|
62
|
+
rows: number;
|
|
63
|
+
columns: number;
|
|
64
|
+
frameIndex: number;
|
|
65
|
+
/** 'boot': frenetic pulse over the streaming boot log; 'ready': the steady instrument. */
|
|
66
|
+
phase: 'boot' | 'ready';
|
|
67
|
+
info: FaceInfo[];
|
|
68
|
+
telemetry: FaceTelemetry | null;
|
|
69
|
+
logTail: string[];
|
|
70
|
+
uptimeSeconds: number;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Formats an uptime as `2d 03:14:07` / `03:14:07`.
|
|
74
|
+
*
|
|
75
|
+
* @param seconds - Whole seconds since the daemon came up.
|
|
76
|
+
* @returns The formatted uptime.
|
|
77
|
+
*/
|
|
78
|
+
export declare function uptime_format(seconds: number): string;
|
|
79
|
+
/**
|
|
80
|
+
* Composes one face frame as screen lines, top to bottom. Pure: no terminal
|
|
81
|
+
* control, no timers — the runtime places these under the alternate buffer
|
|
82
|
+
* and the tests read them directly.
|
|
83
|
+
*
|
|
84
|
+
* @param frame - The readings and geometry for this frame.
|
|
85
|
+
* @returns The lines to paint, at most `frame.rows - 1` of them.
|
|
86
|
+
*/
|
|
87
|
+
export declare function face_frameCompose(frame: FaceFrame): string[];
|
|
88
|
+
/** Whether the console face currently owns the terminal. */
|
|
89
|
+
export declare function face_isActive(): boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Takes the daemon terminal over as the console face.
|
|
92
|
+
*
|
|
93
|
+
* A no-op off a TTY (systemd, nohup, a pipe): the daemon then logs
|
|
94
|
+
* sequentially exactly as before.
|
|
95
|
+
*
|
|
96
|
+
* @param options - Identity rows and live-telemetry hook.
|
|
97
|
+
* @returns True when the face took the screen.
|
|
98
|
+
*/
|
|
99
|
+
export declare function face_start(options: FaceOptions, phase?: 'boot' | 'ready'): boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Takes the terminal over for the boot phase: the brain in its frenetic
|
|
102
|
+
* boot pulse over a tall strip of the streaming boot log — no identity
|
|
103
|
+
* panel yet, because there is nothing to identify. A no-op off a TTY.
|
|
104
|
+
*
|
|
105
|
+
* @returns True when the boot face took the screen.
|
|
106
|
+
*/
|
|
107
|
+
export declare function face_boot(): boolean;
|
|
108
|
+
/**
|
|
109
|
+
* Settles the face into its steady state: the calm ambient pulse, the
|
|
110
|
+
* identity panel, live telemetry, and the toggle hint. Called on a face
|
|
111
|
+
* already up (the boot phase) it repaints in place; called with no face
|
|
112
|
+
* (a host that skipped the boot phase) it starts one. Off a TTY, nothing.
|
|
113
|
+
*
|
|
114
|
+
* @param options - Identity rows and live-telemetry hook.
|
|
115
|
+
* @returns True when a face is showing the steady state.
|
|
116
|
+
*/
|
|
117
|
+
export declare function face_ready(options: FaceOptions): boolean;
|
|
118
|
+
/**
|
|
119
|
+
* Steps aside for an interactive prompt: the terminal returns to the
|
|
120
|
+
* normal buffer with cooked stdin, and the face's key handler stops
|
|
121
|
+
* listening so the prompt's readline owns every keystroke.
|
|
122
|
+
*/
|
|
123
|
+
export declare function face_suspend(): void;
|
|
124
|
+
/** Returns from a prompt: raw keys again, and back onto the face. */
|
|
125
|
+
export declare function face_resume(): void;
|
|
126
|
+
/** Releases the terminal entirely: buffers, writes, raw mode, listeners. */
|
|
127
|
+
export declare function face_stop(): void;
|