@fnndsc/brasa 0.12.0 → 0.14.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/buildinfo.json +1 -1
- package/dist/builtins/fs/archive.d.ts +43 -0
- package/dist/builtins/fs/archive.js +174 -0
- package/dist/builtins/fs/archive.js.map +1 -0
- package/dist/builtins/fs/configWrite.d.ts +16 -0
- package/dist/builtins/fs/configWrite.js +83 -0
- package/dist/builtins/fs/configWrite.js.map +1 -0
- package/dist/builtins/fs/download.d.ts +2 -1
- package/dist/builtins/fs/download.js +108 -2
- package/dist/builtins/fs/download.js.map +1 -1
- package/dist/builtins/fs/pull.js +43 -11
- package/dist/builtins/fs/pull.js.map +1 -1
- package/dist/builtins/help.js +14 -0
- package/dist/builtins/help.js.map +1 -1
- package/dist/builtins/index.d.ts +1 -0
- package/dist/builtins/index.js +1 -0
- package/dist/builtins/index.js.map +1 -1
- package/dist/builtins/net/query.d.ts +16 -0
- package/dist/builtins/net/query.js +104 -3
- package/dist/builtins/net/query.js.map +1 -1
- package/dist/builtins/proc.js +17 -9
- package/dist/builtins/proc.js.map +1 -1
- package/dist/builtins/res/feed.diagram.d.ts +24 -0
- package/dist/builtins/res/feed.diagram.js +66 -2
- package/dist/builtins/res/feed.diagram.js.map +1 -1
- package/dist/builtins/res/feed.js +4 -2
- package/dist/builtins/res/feed.js.map +1 -1
- package/dist/builtins/res/pipeline.diagram.js +27 -4
- package/dist/builtins/res/pipeline.diagram.js.map +1 -1
- package/dist/core/dispatch.js +3 -1
- package/dist/core/dispatch.js.map +1 -1
- package/dist/core/engine.d.ts +17 -0
- package/dist/core/engine.js +8 -1
- package/dist/core/engine.js.map +1 -1
- package/dist/core/progress.d.ts +7 -30
- package/dist/core/progress.js +6 -17
- package/dist/core/progress.js.map +1 -1
- package/dist/core/promptContext.d.ts +15 -0
- package/dist/core/promptContext.js +22 -0
- package/dist/core/promptContext.js.map +1 -1
- package/dist/core/surface.d.ts +34 -0
- package/dist/core/surface.js +7 -0
- package/dist/core/surface.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/spinner.d.ts +48 -9
- package/dist/lib/spinner.js +65 -45
- package/dist/lib/spinner.js.map +1 -1
- package/dist/logo/brain.d.ts +31 -0
- package/dist/logo/brain.js +256 -0
- package/dist/logo/brain.js.map +1 -0
- package/dist/session/index.d.ts +17 -0
- package/dist/session/index.js +20 -0
- package/dist/session/index.js.map +1 -1
- package/package.json +5 -4
|
@@ -13,6 +13,19 @@
|
|
|
13
13
|
import { session } from '../session/index.js';
|
|
14
14
|
import { context_getSingle } from '@fnndsc/salsa';
|
|
15
15
|
import { procCache_get, } from '@fnndsc/cumin';
|
|
16
|
+
/**
|
|
17
|
+
* Snapshots the live process-index counts, cheaply: no network, just the
|
|
18
|
+
* cache's own registers. The daemon's telemetry heartbeat reads this.
|
|
19
|
+
*
|
|
20
|
+
* @returns The jobs and feeds the index currently holds.
|
|
21
|
+
*/
|
|
22
|
+
export function procIndex_snapshot() {
|
|
23
|
+
const cache = procCache_get();
|
|
24
|
+
return {
|
|
25
|
+
jobs: cache.warmupProgress_get().loaded,
|
|
26
|
+
feeds: cache.feedScopeCounts_get('').total,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
16
29
|
/**
|
|
17
30
|
* Builds the current session's prompt context.
|
|
18
31
|
*
|
|
@@ -32,6 +45,14 @@ export async function sessionPromptContext_build(options = {}) {
|
|
|
32
45
|
const procWarmup = warmupRaw.active || lifecycle.state === 'reconciling' || lifecycle.state === 'failed'
|
|
33
46
|
? { loaded: warmupRaw.loaded, total: warmupRaw.total, restored, state: procState }
|
|
34
47
|
: undefined;
|
|
48
|
+
// Steady-state counts stay visible after warm-up settles: warmup progress
|
|
49
|
+
// retains its final figures, and the feed map is the live index.
|
|
50
|
+
const procIndex = warmupRaw.loaded > 0 || procCache_get().feedScopeCounts_get(context.user ?? '').total > 0
|
|
51
|
+
? {
|
|
52
|
+
jobs: warmupRaw.loaded,
|
|
53
|
+
feeds: procCache_get().feedScopeCounts_get(context.user ?? '').total,
|
|
54
|
+
}
|
|
55
|
+
: undefined;
|
|
35
56
|
return {
|
|
36
57
|
user: isOffline ? 'disconnected' : (context.user ?? 'disconnected'),
|
|
37
58
|
uri: isOffline ? 'no-cube' : (context.URL ?? 'no-cube'),
|
|
@@ -41,6 +62,7 @@ export async function sessionPromptContext_build(options = {}) {
|
|
|
41
62
|
lastExitCode: options.lastExitCode ?? 0,
|
|
42
63
|
lastCommandDurationMs: options.lastCommandDurationMs ?? 0,
|
|
43
64
|
procWarmup,
|
|
65
|
+
procIndex,
|
|
44
66
|
};
|
|
45
67
|
}
|
|
46
68
|
//# sourceMappingURL=promptContext.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"promptContext.js","sourceRoot":"","sources":["../../src/core/promptContext.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAEL,aAAa,GAKd,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"promptContext.js","sourceRoot":"","sources":["../../src/core/promptContext.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAEL,aAAa,GAKd,MAAM,eAAe,CAAC;AAkCvB;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,KAAK,GAAG,aAAa,EAAE,CAAC;IAC9B,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,kBAAkB,EAAE,CAAC,MAAM;QACvC,KAAK,EAAE,KAAK,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC,KAAK;KAC3C,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,UAAuC,EAAE;IAEzC,MAAM,OAAO,GAAkB,MAAM,iBAAiB,EAAE,CAAC;IACzD,MAAM,GAAG,GAAW,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC;IAC3C,MAAM,SAAS,GAAY,OAAO,CAAC,OAAO,CAAC;IAE3C,MAAM,SAAS,GAAuB,aAAa,EAAE,CAAC,kBAAkB,EAAE,CAAC;IAC3E,MAAM,SAAS,GAAuB,aAAa,EAAE,CAAC,aAAa,EAAE,CAAC;IACtE,MAAM,QAAQ,GAAY,SAAS,CAAC,YAAY,KAAK,SAAS,CAAC;IAC/D,MAAM,SAAS,GAAoB,SAAS,CAAC,KAAK,KAAK,QAAQ;QAC7D,CAAC,CAAC,QAAQ;QACV,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;IACjC,MAAM,UAAU,GACd,SAAS,CAAC,MAAM,IAAI,SAAS,CAAC,KAAK,KAAK,aAAa,IAAI,SAAS,CAAC,KAAK,KAAK,QAAQ;QACnF,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE;QAClF,CAAC,CAAC,SAAS,CAAC;IAChB,0EAA0E;IAC1E,iEAAiE;IACjE,MAAM,SAAS,GACb,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,aAAa,EAAE,CAAC,mBAAmB,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC;QACvF,CAAC,CAAC;YACE,IAAI,EAAE,SAAS,CAAC,MAAM;YACtB,KAAK,EAAE,aAAa,EAAE,CAAC,mBAAmB,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,KAAK;SACrE;QACH,CAAC,CAAC,SAAS,CAAC;IAEhB,OAAO;QACL,IAAI,EAAmB,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,IAAI,cAAc,CAAC;QACpF,GAAG,EAAoB,SAAS,CAAC,CAAC,CAAC,SAAS,CAAM,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,IAAK,SAAS,CAAC;QAC/E,GAAG,EAAoB,SAAS,CAAC,CAAC,CAAC,GAAG,CAAY,CAAC,CAAC,GAAG;QACvD,UAAU,EAAa,OAAO,CAAC,UAAU,IAAI,IAAI;QACjD,YAAY,EAAW,OAAO,CAAC,gBAAgB,EAAE;QACjD,YAAY,EAAW,OAAO,CAAC,YAAY,IAAI,CAAC;QAChD,qBAAqB,EAAE,OAAO,CAAC,qBAAqB,IAAI,CAAC;QACzD,UAAU;QACV,SAAS;KACV,CAAC;AACJ,CAAC"}
|
package/dist/core/surface.d.ts
CHANGED
|
@@ -40,6 +40,20 @@
|
|
|
40
40
|
* @property shellCommands - The surface can run a `!`-prefixed host-shell
|
|
41
41
|
* command on its own machine. A daemon delegates this capability to the
|
|
42
42
|
* command's originating surface and never launches the process itself.
|
|
43
|
+
* @property fileDelivery - The surface can put a file where its operator can
|
|
44
|
+
* reach it. What that means is the surface's business — a path on the local
|
|
45
|
+
* CLI's disk, a path on a remote CLI's client machine, a saved file in a
|
|
46
|
+
* browser — but never the daemon host's disk.
|
|
47
|
+
* @property engineFilesystem - The surface's operator sits at the same
|
|
48
|
+
* filesystem the engine runs on, so a path the engine resolves is a path
|
|
49
|
+
* they can open. True only for an in-process local shell. When false, a
|
|
50
|
+
* builtin that would write to disk must deliver through the surface instead,
|
|
51
|
+
* because the engine's disk is somebody else's machine.
|
|
52
|
+
* @property localFilesystem - The surface can put many files into a directory
|
|
53
|
+
* structure of its own. True for any shell, remote included; false for a
|
|
54
|
+
* browser, which has no directory to fill and can only accept files one at a
|
|
55
|
+
* time. It answers a different question from `engineFilesystem`: not *whose*
|
|
56
|
+
* disk, but whether there is one at all.
|
|
43
57
|
*/
|
|
44
58
|
export interface SurfaceCapabilities {
|
|
45
59
|
hiddenInput: boolean;
|
|
@@ -47,6 +61,9 @@ export interface SurfaceCapabilities {
|
|
|
47
61
|
tty: boolean;
|
|
48
62
|
pipeSegments: boolean;
|
|
49
63
|
shellCommands: boolean;
|
|
64
|
+
fileDelivery: boolean;
|
|
65
|
+
engineFilesystem: boolean;
|
|
66
|
+
localFilesystem: boolean;
|
|
50
67
|
}
|
|
51
68
|
/**
|
|
52
69
|
* A request to prompt the user for a line of input.
|
|
@@ -70,6 +87,8 @@ export interface LocalEditRequest {
|
|
|
70
87
|
content: string;
|
|
71
88
|
extension?: string;
|
|
72
89
|
}
|
|
90
|
+
export type { FileDeliverRequest, FileDeliverResult } from '@fnndsc/menu';
|
|
91
|
+
import type { FileDeliverRequest, FileDeliverResult } from '@fnndsc/menu';
|
|
73
92
|
/**
|
|
74
93
|
* The outcome of a local edit.
|
|
75
94
|
*
|
|
@@ -129,6 +148,19 @@ export interface Surface {
|
|
|
129
148
|
* capability.
|
|
130
149
|
*/
|
|
131
150
|
localEdit(request: LocalEditRequest): Promise<LocalEditResult>;
|
|
151
|
+
/**
|
|
152
|
+
* Places one file where this surface's operator can reach it.
|
|
153
|
+
*
|
|
154
|
+
* The mechanics are the surface's: a write to the resolved path for the
|
|
155
|
+
* local CLI, a write on the client machine for a remote CLI, a saved file
|
|
156
|
+
* for a browser. A daemon never writes to its own disk on a surface's
|
|
157
|
+
* behalf, for the same reason it never spawns a shell there.
|
|
158
|
+
*
|
|
159
|
+
* @param request - What to deliver and where the operator asked for it.
|
|
160
|
+
* @returns Where it landed and how large it was.
|
|
161
|
+
* @throws {CapabilityError} When the surface lacks `fileDelivery`.
|
|
162
|
+
*/
|
|
163
|
+
fileDeliver(request: FileDeliverRequest): Promise<FileDeliverResult>;
|
|
132
164
|
}
|
|
133
165
|
/**
|
|
134
166
|
* Raised when a builtin requests an interaction the attached surface cannot
|
|
@@ -161,6 +193,8 @@ export declare class HeadlessSurface implements Surface {
|
|
|
161
193
|
shellCommand(_command: string): Promise<number>;
|
|
162
194
|
/** @inheritdoc */
|
|
163
195
|
localEdit(_request: LocalEditRequest): Promise<LocalEditResult>;
|
|
196
|
+
/** @inheritdoc */
|
|
197
|
+
fileDeliver(_request: FileDeliverRequest): Promise<FileDeliverResult>;
|
|
164
198
|
}
|
|
165
199
|
/**
|
|
166
200
|
* Returns the currently installed surface.
|
package/dist/core/surface.js
CHANGED
|
@@ -55,6 +55,9 @@ export class HeadlessSurface {
|
|
|
55
55
|
tty: false,
|
|
56
56
|
pipeSegments: false,
|
|
57
57
|
shellCommands: false,
|
|
58
|
+
fileDelivery: false,
|
|
59
|
+
engineFilesystem: false,
|
|
60
|
+
localFilesystem: false,
|
|
58
61
|
};
|
|
59
62
|
/** @inheritdoc */
|
|
60
63
|
prompt(_request) {
|
|
@@ -72,6 +75,10 @@ export class HeadlessSurface {
|
|
|
72
75
|
localEdit(_request) {
|
|
73
76
|
throw new CapabilityError('localEdit', 'This surface cannot open a local editor.');
|
|
74
77
|
}
|
|
78
|
+
/** @inheritdoc */
|
|
79
|
+
fileDeliver(_request) {
|
|
80
|
+
throw new CapabilityError('fileDelivery', 'This surface cannot receive a file.');
|
|
81
|
+
}
|
|
75
82
|
}
|
|
76
83
|
/** The active surface. Defaults to headless until a host installs one. */
|
|
77
84
|
let activeSurface = new HeadlessSurface();
|
package/dist/core/surface.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"surface.js","sourceRoot":"","sources":["../../src/core/surface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;
|
|
1
|
+
{"version":3,"file":"surface.js","sourceRoot":"","sources":["../../src/core/surface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AA+JH;;;GAGG;AACH,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACxC,mDAAmD;IACnC,UAAU,CAA4B;IAEtD;;;OAGG;IACH,YAAY,UAAqC,EAAE,OAAe;QAChE,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;QAC9B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;CACF;AAED;;;;;;GAMG;AACH,MAAM,OAAO,eAAe;IAC1B,kBAAkB;IACF,YAAY,GAAwB;QAClD,WAAW,EAAE,KAAK;QAClB,SAAS,EAAE,KAAK;QAChB,GAAG,EAAE,KAAK;QACV,YAAY,EAAE,KAAK;QACnB,aAAa,EAAE,KAAK;QACpB,YAAY,EAAE,KAAK;QACnB,gBAAgB,EAAE,KAAK;QACvB,eAAe,EAAE,KAAK;KACvB,CAAC;IAEF,kBAAkB;IACX,MAAM,CAAC,QAAuB;QACnC,MAAM,IAAI,eAAe,CAAC,KAAK,EAAE,uCAAuC,CAAC,CAAC;IAC5E,CAAC;IAED,kBAAkB;IACX,WAAW,CAAC,QAAgB,EAAE,MAAc;QACjD,MAAM,IAAI,eAAe,CAAC,cAAc,EAAE,4CAA4C,CAAC,CAAC;IAC1F,CAAC;IAED,kBAAkB;IACX,YAAY,CAAC,QAAgB;QAClC,MAAM,IAAI,eAAe,CAAC,eAAe,EAAE,yCAAyC,CAAC,CAAC;IACxF,CAAC;IAED,kBAAkB;IACX,SAAS,CAAC,QAA0B;QACzC,MAAM,IAAI,eAAe,CAAC,WAAW,EAAE,0CAA0C,CAAC,CAAC;IACrF,CAAC;IAED,kBAAkB;IACX,WAAW,CAAC,QAA4B;QAC7C,MAAM,IAAI,eAAe,CAAC,cAAc,EAAE,qCAAqC,CAAC,CAAC;IACnF,CAAC;CACF;AAED,0EAA0E;AAC1E,IAAI,aAAa,GAAY,IAAI,eAAe,EAAE,CAAC;AAEnD;;;;GAIG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,OAAgB;IAC1C,MAAM,QAAQ,GAAY,aAAa,CAAC;IACxC,aAAa,GAAG,OAAO,CAAC;IACxB,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAChC,UAAqC,EACrC,OAAe;IAEf,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,eAAe,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ export * from './builtins/index.js';
|
|
|
26
26
|
export * from './config/storeConfig.js';
|
|
27
27
|
export * from './lib/vfs/vfs.js';
|
|
28
28
|
export * from './lib/spinner.js';
|
|
29
|
+
export * from './logo/brain.js';
|
|
29
30
|
export * from './lib/prefetch.js';
|
|
30
31
|
export * from './lib/parser.js';
|
|
31
32
|
export * from './lib/pipe.js';
|
package/dist/index.js
CHANGED
|
@@ -27,6 +27,7 @@ export * from './builtins/index.js';
|
|
|
27
27
|
export * from './config/storeConfig.js';
|
|
28
28
|
export * from './lib/vfs/vfs.js';
|
|
29
29
|
export * from './lib/spinner.js';
|
|
30
|
+
export * from './logo/brain.js';
|
|
30
31
|
export * from './lib/prefetch.js';
|
|
31
32
|
export * from './lib/parser.js';
|
|
32
33
|
export * from './lib/pipe.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,cAAc,kBAAkB,CAAC;AACjC,iEAAiE;AACjE,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,cAAc,kBAAkB,CAAC;AACjC,iEAAiE;AACjE,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC"}
|
package/dist/lib/spinner.d.ts
CHANGED
|
@@ -1,23 +1,62 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @file
|
|
2
|
+
* @file Indeterminate-progress announcer for long-running work.
|
|
3
|
+
*
|
|
4
|
+
* A command that cannot say how much work remains still owes the operator the
|
|
5
|
+
* fact that work is under way. This announces that fact as a structured
|
|
6
|
+
* progress event; it does not draw it. Frame choreography — the braille cycle,
|
|
7
|
+
* the erase-line, the elapsed counter — belongs to whichever renderer is
|
|
8
|
+
* attached, because a browser, a terminal and a log each express waiting
|
|
9
|
+
* differently and none of them should have to recover meaning from cursor
|
|
10
|
+
* movement.
|
|
11
|
+
*
|
|
12
|
+
* The class keeps its former name and call signature so its many callers need
|
|
13
|
+
* no change, but it is no longer a terminal utility: it emits `operation:
|
|
14
|
+
* 'task'` with `kind: 'inspection'`, and the surface decides the rest.
|
|
3
15
|
*
|
|
4
16
|
* @module
|
|
5
17
|
*/
|
|
6
18
|
/**
|
|
7
|
-
*
|
|
19
|
+
* Announces indeterminate progress for async work.
|
|
20
|
+
*
|
|
21
|
+
* `start` opens an announcement, `updateMessage` revises its label, and `stop`
|
|
22
|
+
* closes it. Only state changes cross the wire: a spin that lasts a minute
|
|
23
|
+
* costs two events, not one per animation frame.
|
|
8
24
|
*/
|
|
9
25
|
export declare class Spinner {
|
|
10
|
-
private interval;
|
|
11
26
|
private message;
|
|
12
|
-
private frames;
|
|
13
|
-
private frameIndex;
|
|
14
27
|
private spinnerActive;
|
|
15
|
-
|
|
16
|
-
|
|
28
|
+
/**
|
|
29
|
+
* @param initialMessage - Label used when `start` is called without one.
|
|
30
|
+
*/
|
|
17
31
|
constructor(initialMessage?: string);
|
|
18
|
-
|
|
19
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Opens an indeterminate-progress announcement.
|
|
34
|
+
*
|
|
35
|
+
* @param message - Label describing the work; defaults to the last label set.
|
|
36
|
+
* @param _showTiming - Retained for call-site compatibility. Elapsed time is
|
|
37
|
+
* now the renderer's to measure and display, since only the renderer knows
|
|
38
|
+
* whether it can show a live counter at all.
|
|
39
|
+
*/
|
|
40
|
+
start(message?: string, _showTiming?: boolean): void;
|
|
41
|
+
/**
|
|
42
|
+
* Closes the announcement.
|
|
43
|
+
*
|
|
44
|
+
* @param _clearLine - Retained for call-site compatibility. Whether closing
|
|
45
|
+
* erases anything is a rendering decision.
|
|
46
|
+
*/
|
|
47
|
+
stop(_clearLine?: boolean): void;
|
|
48
|
+
/**
|
|
49
|
+
* Revises the label of an open announcement.
|
|
50
|
+
*
|
|
51
|
+
* @param newMessage - The label to show from now on.
|
|
52
|
+
*/
|
|
20
53
|
updateMessage(newMessage: string): void;
|
|
54
|
+
/**
|
|
55
|
+
* Emits one progress event for the current label.
|
|
56
|
+
*
|
|
57
|
+
* @param phase - The lifecycle phase this event reports.
|
|
58
|
+
*/
|
|
59
|
+
private progress_emit;
|
|
21
60
|
}
|
|
22
61
|
declare const globalSpinner: Spinner;
|
|
23
62
|
export { globalSpinner as spinner };
|
package/dist/lib/spinner.js
CHANGED
|
@@ -1,69 +1,89 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @file
|
|
2
|
+
* @file Indeterminate-progress announcer for long-running work.
|
|
3
|
+
*
|
|
4
|
+
* A command that cannot say how much work remains still owes the operator the
|
|
5
|
+
* fact that work is under way. This announces that fact as a structured
|
|
6
|
+
* progress event; it does not draw it. Frame choreography — the braille cycle,
|
|
7
|
+
* the erase-line, the elapsed counter — belongs to whichever renderer is
|
|
8
|
+
* attached, because a browser, a terminal and a log each express waiting
|
|
9
|
+
* differently and none of them should have to recover meaning from cursor
|
|
10
|
+
* movement.
|
|
11
|
+
*
|
|
12
|
+
* The class keeps its former name and call signature so its many callers need
|
|
13
|
+
* no change, but it is no longer a terminal utility: it emits `operation:
|
|
14
|
+
* 'task'` with `kind: 'inspection'`, and the surface decides the rest.
|
|
3
15
|
*
|
|
4
16
|
* @module
|
|
5
17
|
*/
|
|
6
|
-
import chalk from 'chalk';
|
|
7
18
|
import { sink_get } from '../core/sink.js';
|
|
8
19
|
/**
|
|
9
|
-
*
|
|
20
|
+
* Announces indeterminate progress for async work.
|
|
21
|
+
*
|
|
22
|
+
* `start` opens an announcement, `updateMessage` revises its label, and `stop`
|
|
23
|
+
* closes it. Only state changes cross the wire: a spin that lasts a minute
|
|
24
|
+
* costs two events, not one per animation frame.
|
|
10
25
|
*/
|
|
11
26
|
export class Spinner {
|
|
12
|
-
interval = null;
|
|
13
27
|
message = '';
|
|
14
|
-
frames = ["⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷"];
|
|
15
|
-
frameIndex = 0;
|
|
16
28
|
spinnerActive = false;
|
|
17
|
-
|
|
18
|
-
|
|
29
|
+
/**
|
|
30
|
+
* @param initialMessage - Label used when `start` is called without one.
|
|
31
|
+
*/
|
|
19
32
|
constructor(initialMessage = 'Loading...') {
|
|
20
33
|
this.message = initialMessage;
|
|
21
34
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Opens an indeterminate-progress announcement.
|
|
37
|
+
*
|
|
38
|
+
* @param message - Label describing the work; defaults to the last label set.
|
|
39
|
+
* @param _showTiming - Retained for call-site compatibility. Elapsed time is
|
|
40
|
+
* now the renderer's to measure and display, since only the renderer knows
|
|
41
|
+
* whether it can show a live counter at all.
|
|
42
|
+
*/
|
|
43
|
+
start(message, _showTiming = false) {
|
|
27
44
|
if (this.spinnerActive) {
|
|
28
|
-
this.stop();
|
|
45
|
+
this.stop();
|
|
29
46
|
}
|
|
30
|
-
this.message = message
|
|
47
|
+
this.message = message ?? this.message;
|
|
31
48
|
this.spinnerActive = true;
|
|
32
|
-
this.
|
|
33
|
-
this.showTiming = showTiming;
|
|
34
|
-
this.startTime = Date.now();
|
|
35
|
-
// Hide cursor
|
|
36
|
-
sink_get().status_write('\x1B[?25l');
|
|
37
|
-
this.interval = setInterval(() => {
|
|
38
|
-
const frame = this.frames[this.frameIndex = (this.frameIndex + 1) % this.frames.length];
|
|
39
|
-
let displayMessage = this.message;
|
|
40
|
-
// Add timing if enabled
|
|
41
|
-
if (this.showTiming) {
|
|
42
|
-
const elapsedSeconds = ((Date.now() - this.startTime) / 1000).toFixed(1);
|
|
43
|
-
displayMessage = `${this.message} (${elapsedSeconds}s)`;
|
|
44
|
-
}
|
|
45
|
-
// Note: We use chalk.gray for the message to match the existing "Fetching..." style.
|
|
46
|
-
// \x1b[K erases to end-of-line so a shorter message never leaves the
|
|
47
|
-
// tail of a longer previous one behind.
|
|
48
|
-
sink_get().status_write(`\r\x1b[K${chalk.bgBlack.cyanBright.bold(frame)} ${chalk.gray(displayMessage)}`);
|
|
49
|
-
}, 80);
|
|
49
|
+
this.progress_emit('working');
|
|
50
50
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
// Show cursor
|
|
61
|
-
sink_get().status_write('\x1B[?25h');
|
|
62
|
-
this.spinnerActive = false;
|
|
51
|
+
/**
|
|
52
|
+
* Closes the announcement.
|
|
53
|
+
*
|
|
54
|
+
* @param _clearLine - Retained for call-site compatibility. Whether closing
|
|
55
|
+
* erases anything is a rendering decision.
|
|
56
|
+
*/
|
|
57
|
+
stop(_clearLine = true) {
|
|
58
|
+
if (!this.spinnerActive) {
|
|
59
|
+
return;
|
|
63
60
|
}
|
|
61
|
+
this.spinnerActive = false;
|
|
62
|
+
this.progress_emit('complete');
|
|
64
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Revises the label of an open announcement.
|
|
66
|
+
*
|
|
67
|
+
* @param newMessage - The label to show from now on.
|
|
68
|
+
*/
|
|
65
69
|
updateMessage(newMessage) {
|
|
66
70
|
this.message = newMessage;
|
|
71
|
+
if (this.spinnerActive) {
|
|
72
|
+
this.progress_emit('working');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Emits one progress event for the current label.
|
|
77
|
+
*
|
|
78
|
+
* @param phase - The lifecycle phase this event reports.
|
|
79
|
+
*/
|
|
80
|
+
progress_emit(phase) {
|
|
81
|
+
sink_get().progress_write({
|
|
82
|
+
operation: 'task',
|
|
83
|
+
kind: 'inspection',
|
|
84
|
+
phase,
|
|
85
|
+
label: this.message,
|
|
86
|
+
});
|
|
67
87
|
}
|
|
68
88
|
}
|
|
69
89
|
const globalSpinner = new Spinner();
|
package/dist/lib/spinner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spinner.js","sourceRoot":"","sources":["../../src/lib/spinner.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"spinner.js","sourceRoot":"","sources":["../../src/lib/spinner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE3C;;;;;;GAMG;AACH,MAAM,OAAO,OAAO;IACV,OAAO,GAAW,EAAE,CAAC;IACrB,aAAa,GAAY,KAAK,CAAC;IAEvC;;OAEG;IACH,YAAY,iBAAyB,YAAY;QAC/C,IAAI,CAAC,OAAO,GAAG,cAAc,CAAC;IAChC,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,OAAgB,EAAE,cAAuB,KAAK;QACzD,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC;QACvC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IAChC,CAAC;IAED;;;;;OAKG;IACI,IAAI,CAAC,aAAsB,IAAI;QACpC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;QAC3B,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACI,aAAa,CAAC,UAAkB;QACrC,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC;QAC1B,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED;;;;OAIG;IACK,aAAa,CAAC,KAA6B;QACjD,QAAQ,EAAE,CAAC,cAAc,CAAC;YACxB,SAAS,EAAE,MAAM;YACjB,IAAI,EAAE,YAAY;YAClB,KAAK;YACL,KAAK,EAAE,IAAI,CAAC,OAAO;SACpB,CAAC,CAAC;IACL,CAAC;CACF;AAED,MAAM,aAAa,GAAY,IAAI,OAAO,EAAE,CAAC;AAC7C,OAAO,EAAE,aAAa,IAAI,OAAO,EAAE,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renders the ASCII logo as an array of lines.
|
|
3
|
+
*
|
|
4
|
+
* @param colorize - Whether to apply color.
|
|
5
|
+
* @param reverse - Whether to reverse the gradient.
|
|
6
|
+
* @returns The rendered logo lines.
|
|
7
|
+
*/
|
|
8
|
+
export declare function logo_linesRender(colorize: boolean, reverse?: boolean): string[];
|
|
9
|
+
/**
|
|
10
|
+
* Renders a single frame of the brain activity animation, where the core brain
|
|
11
|
+
* structure retains its original hue'd color gradient, and only the inner spaces
|
|
12
|
+
* (stylized nodes) pulse, grow, and fade physically as spatial blooms.
|
|
13
|
+
*
|
|
14
|
+
* @param frameIndex - The index of the animation frame.
|
|
15
|
+
* @param isStaticEndState - If true, renders the final steady state where holes are blank.
|
|
16
|
+
* @returns Array of rendered lines with color codes.
|
|
17
|
+
*/
|
|
18
|
+
export declare function logo_frameRender(frameIndex: number, isStaticEndState?: boolean): string[];
|
|
19
|
+
/**
|
|
20
|
+
* The number of terminal rows one rendered frame occupies.
|
|
21
|
+
*
|
|
22
|
+
* @returns The frame height in rows.
|
|
23
|
+
*/
|
|
24
|
+
export declare function logoRows_count(): number;
|
|
25
|
+
/**
|
|
26
|
+
* The number of terminal columns the widest rendered line occupies,
|
|
27
|
+
* including the two-column indent every frame line carries.
|
|
28
|
+
*
|
|
29
|
+
* @returns The frame width in columns.
|
|
30
|
+
*/
|
|
31
|
+
export declare function logoColumns_count(): number;
|