@executablemd/runtime 0.12.0 → 0.13.1

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/esm/api.js ADDED
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @module
3
+ *
4
+ * The consumer API of `@executablemd/runtime`: the shared execution
5
+ * configuration a Plugin, a component package or a host reads.
6
+ *
7
+ * `Config` is the same Api the engine and the CLI already install and read;
8
+ * this entrypoint is where a consumer imports it from, so a package depending
9
+ * on runtime reaches its configuration without importing the whole host
10
+ * surface. The root export keeps every one of these names.
11
+ *
12
+ * ```ts
13
+ * import { verbose } from "@executablemd/runtime/api";
14
+ *
15
+ * if (yield* verbose) {
16
+ * // render the detail a quiet run leaves out
17
+ * }
18
+ * ```
19
+ */
20
+ import "./_dnt.polyfills.js";
21
+ export { Config, timeout, timeoutExec, timeoutFetch, verbose } from "./config.js";
22
+ export { asDuration, durationError, parseDuration } from "./duration.js";
package/esm/config.js CHANGED
@@ -26,7 +26,7 @@
26
26
  * `verbose` is the fourth field and is not a timeout. It says whether the
27
27
  * scope reading it renders verbose-only content, it is `false` until something
28
28
  * says otherwise, and it is installed and overridden exactly the way a timeout
29
- * is. It bounds nothing, opens nothing and decides nothing about authority: a
29
+ * is. It bounds nothing, opens nothing and decides no permission: a
30
30
  * component reads it to choose between rendering its content and rendering
31
31
  * nothing, and the host's own presentation — the journal, the event echo, the
32
32
  * testing report — is decided by the command line rather than by this field.
package/esm/files.js CHANGED
@@ -20,7 +20,7 @@
20
20
  *
21
21
  * `checkFilePath` is the one exception, and it is deliberately weak: pure path
22
22
  * arithmetic, no filesystem access, and nothing usable comes back — no path, no
23
- * handle, no authority token. `<File>`'s write form calls it to decide whether
23
+ * handle, no capability token. `<File>`'s write form calls it to decide whether
24
24
  * its children may expand at all, and the later `writeTextFile` repeats the
25
25
  * same admission from the same authored path. A check that was skipped,
26
26
  * replaced, or answered by another provider therefore authorizes nothing.
package/esm/launcher.js CHANGED
@@ -52,6 +52,10 @@ export const NativeLauncher = createApi("runtime.nativeLauncher", {
52
52
  *launch(_request) {
53
53
  throw new NativeLauncherUnavailableError();
54
54
  },
55
+ // deno-lint-ignore require-yield
56
+ *notify(_text) {
57
+ throw new NativeLauncherUnavailableError();
58
+ },
55
59
  });
56
60
  /** Hold the foreground-terminal lease for the calling scope. */
57
61
  export function reserveTerminal() {
@@ -61,6 +65,10 @@ export function reserveTerminal() {
61
65
  export function flushOutput() {
62
66
  return NativeLauncher.operations.flush();
63
67
  }
68
+ /** Say one thing to whoever is at the terminal this launch reserved. */
69
+ export function notifyTerminal(text) {
70
+ return NativeLauncher.operations.notify(text);
71
+ }
64
72
  /** Run one native UI as a foreground child and report how it ended. */
65
73
  export function nativeLaunch(request) {
66
74
  return NativeLauncher.operations.launch(request);
@@ -118,6 +126,12 @@ export function* installForegroundLauncher(options = {}) {
118
126
  *launch([request]) {
119
127
  return yield* runForeground(request);
120
128
  },
129
+ *notify([text]) {
130
+ // Written and drained, not queued: the next thing to reach this
131
+ // terminal may be a child drawing over it.
132
+ process.stdout.write(`${text}\n`);
133
+ yield* drainStream(process.stdout);
134
+ },
121
135
  }, { at: "min" });
122
136
  }
123
137
  /**
@@ -329,6 +343,10 @@ export function* installControlledLauncher(options = {}) {
329
343
  *flush() {
330
344
  options.onFlush?.();
331
345
  },
346
+ // deno-lint-ignore require-yield
347
+ *notify([text]) {
348
+ options.onNotify?.(text);
349
+ },
332
350
  *launch([request]) {
333
351
  options.record?.(request);
334
352
  if (options.wait) {
package/esm/mod.js CHANGED
@@ -18,7 +18,7 @@
18
18
  * (`cwd`, `env`, `platform`, `command`, `compile`)
19
19
  * - `API.Service` — scoped attached service startup (`startService`)
20
20
  * - `NativeLauncher` — handing one native agent UI the foreground terminal
21
- * (`reserveTerminal`, `flushOutput`, `nativeLaunch`)
21
+ * (`reserveTerminal`, `flushOutput`, `notifyTerminal`, `nativeLaunch`)
22
22
  * - `Config` — shared execution config (`timeout`, `timeoutExec`, `timeoutFetch`,
23
23
  * `verbose`)
24
24
  *
@@ -32,7 +32,7 @@ export { Service, SERVICE_HOSTNAME, SERVICE_READY_PREFIX, ServiceProcessExitBefo
32
32
  export { Config, timeout, timeoutExec, timeoutFetch, verbose } from "./config.js";
33
33
  export { asDuration, durationError, parseDuration } from "./duration.js";
34
34
  export { asFilesFatal, FILES_ERROR, FILES_ERROR_MESSAGE, FILES_FATAL, FILES_INVARIANT_MESSAGE, FILES_OPERATION_DENIED_MESSAGE, FILES_PROVIDER_UNAVAILABLE_MESSAGE, FILES_WRITE_SUCCESS, Files, FilesError, FilesInvariantError, FilesOperationDeniedError, FilesProviderUnavailableError, fileWriteFailure, fileWriteSuccess, filesFailure, isFilesFatal, parseFilesPhase, parseFilesReason, parseFileWriteFailure, parseFileWritePhase, parseFileWriteSuccess, parseFilesFailure, parseFilesFatal, } from "./files.js";
35
- export { flushOutput, installControlledLauncher, installForegroundLauncher, NATIVE_LAUNCHER_UNAVAILABLE, NativeLauncher, NativeLauncherUnavailableError, nativeLaunch, NO_TERMINAL, reserveTerminal, } from "./launcher.js";
35
+ export { flushOutput, installControlledLauncher, installForegroundLauncher, NATIVE_LAUNCHER_UNAVAILABLE, NativeLauncher, NativeLauncherUnavailableError, nativeLaunch, NO_TERMINAL, notifyTerminal, reserveTerminal, } from "./launcher.js";
36
36
  export { hostFilesHandler, useHostFiles } from "./host-files.js";
37
37
  export { AgentSessionBusy, agentSessionKeyDigest, AgentSessionRecoveryRequired, parseAgentSessionOwnership, serializeAgentSessionOwnership, } from "./agent-session-coordinator.js";
38
38
  export { createDenoAgentSessionCoordinator, hasDenoAgentSessionCoordinator, } from "./deno-agent-session-coordinator.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@executablemd/runtime",
3
- "version": "0.12.0",
3
+ "version": "0.13.1",
4
4
  "description": "Runtime host APIs for executable.md documents.",
5
5
  "homepage": "https://executable.md",
6
6
  "repository": {
@@ -20,6 +20,12 @@
20
20
  "default": "./esm/mod.js"
21
21
  }
22
22
  },
23
+ "./api": {
24
+ "import": {
25
+ "types": "./types/api.d.ts",
26
+ "default": "./esm/api.js"
27
+ }
28
+ },
23
29
  "./files": {
24
30
  "import": {
25
31
  "types": "./types/files.d.ts",
package/types/api.d.ts ADDED
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @module
3
+ *
4
+ * The consumer API of `@executablemd/runtime`: the shared execution
5
+ * configuration a Plugin, a component package or a host reads.
6
+ *
7
+ * `Config` is the same Api the engine and the CLI already install and read;
8
+ * this entrypoint is where a consumer imports it from, so a package depending
9
+ * on runtime reaches its configuration without importing the whole host
10
+ * surface. The root export keeps every one of these names.
11
+ *
12
+ * ```ts
13
+ * import { verbose } from "@executablemd/runtime/api";
14
+ *
15
+ * if (yield* verbose) {
16
+ * // render the detail a quiet run leaves out
17
+ * }
18
+ * ```
19
+ */
20
+ import "./_dnt.polyfills.js";
21
+ export { Config, timeout, timeoutExec, timeoutFetch, verbose } from "./config.js";
22
+ export type { ConfigApi } from "./config.js";
23
+ export { asDuration, durationError, parseDuration } from "./duration.js";
package/types/config.d.ts CHANGED
@@ -26,7 +26,7 @@
26
26
  * `verbose` is the fourth field and is not a timeout. It says whether the
27
27
  * scope reading it renders verbose-only content, it is `false` until something
28
28
  * says otherwise, and it is installed and overridden exactly the way a timeout
29
- * is. It bounds nothing, opens nothing and decides nothing about authority: a
29
+ * is. It bounds nothing, opens nothing and decides no permission: a
30
30
  * component reads it to choose between rendering its content and rendering
31
31
  * nothing, and the host's own presentation — the journal, the event echo, the
32
32
  * testing report — is decided by the command line rather than by this field.
package/types/files.d.ts CHANGED
@@ -20,7 +20,7 @@
20
20
  *
21
21
  * `checkFilePath` is the one exception, and it is deliberately weak: pure path
22
22
  * arithmetic, no filesystem access, and nothing usable comes back — no path, no
23
- * handle, no authority token. `<File>`'s write form calls it to decide whether
23
+ * handle, no capability token. `<File>`'s write form calls it to decide whether
24
24
  * its children may expand at all, and the later `writeTextFile` repeats the
25
25
  * same admission from the same authored path. A check that was skipped,
26
26
  * replaced, or answered by another provider therefore authorizes nothing.
@@ -172,10 +172,14 @@ export type FilesDeniableOperation = "temporary-directory";
172
172
  /**
173
173
  * Which contract a provider broke.
174
174
  *
175
- * `authority` — the identity authorizing access is stale, foreign, or gone.
175
+ * `authority` — the identity permitting access is stale, foreign, or gone.
176
176
  * `savepoint` — a nested transaction could not be rolled back or released.
177
177
  * `protocol` — a handler threw, or returned data no consumer can trust.
178
178
  * `teardown` — cleanup failed while the scope was already unwinding.
179
+ *
180
+ * `authority` keeps that spelling because it is a serialized value: it crosses
181
+ * loaded copies and reaches parsers that match it byte for byte, so renaming it
182
+ * would break categorization rather than describe it better.
179
183
  */
180
184
  export type FilesInvariantCategory = "authority" | "savepoint" | "protocol" | "teardown";
181
185
  /**
@@ -56,6 +56,21 @@ export interface NativeLauncherHandler {
56
56
  reserve(): Operation<void>;
57
57
  flush(): Operation<void>;
58
58
  launch(request: NativeLaunchRequest): Operation<NativeLaunchOutcome>;
59
+ /**
60
+ * Show the person one line about the launch itself, on the terminal this
61
+ * launch reserved.
62
+ *
63
+ * Not document output. What a launch has to say — that a turn is about to be
64
+ * spent in their name, what it answered, what it cost — is addressed to
65
+ * whoever is sitting there, and it belongs on the screen the native UI is
66
+ * about to open on rather than in the document's captured text, where a
67
+ * `<File>` would keep it and a replay would print it again.
68
+ *
69
+ * It goes through the launcher for the same reason `flush` does: this is the
70
+ * only thing that knows which terminal a given launch owns, so the root's
71
+ * launch writes to the root terminal.
72
+ */
73
+ notify(text: string): Operation<void>;
59
74
  }
60
75
  export declare const NATIVE_LAUNCHER_UNAVAILABLE: string;
61
76
  export declare class NativeLauncherUnavailableError extends Error {
@@ -67,6 +82,8 @@ export declare const NativeLauncher: Api<NativeLauncherHandler>;
67
82
  export declare function reserveTerminal(): Operation<void>;
68
83
  /** Give the reader everything the document has produced so far. */
69
84
  export declare function flushOutput(): Operation<void>;
85
+ /** Say one thing to whoever is at the terminal this launch reserved. */
86
+ export declare function notifyTerminal(text: string): Operation<void>;
70
87
  /** Run one native UI as a foreground child and report how it ended. */
71
88
  export declare function nativeLaunch(request: NativeLaunchRequest): Operation<NativeLaunchOutcome>;
72
89
  export declare const NO_TERMINAL: string;
@@ -119,6 +136,8 @@ export interface ControlledLauncherOptions {
119
136
  wait?: (request: NativeLaunchRequest) => Operation<void>;
120
137
  onReserve?: () => void;
121
138
  onFlush?: () => void;
139
+ /** Each line the launch addressed to the terminal, in the order it said them. */
140
+ onNotify?: (text: string) => void;
122
141
  }
123
142
  export declare function installControlledLauncher(options?: ControlledLauncherOptions): Operation<void>;
124
143
  export {};
package/types/mod.d.ts CHANGED
@@ -18,7 +18,7 @@
18
18
  * (`cwd`, `env`, `platform`, `command`, `compile`)
19
19
  * - `API.Service` — scoped attached service startup (`startService`)
20
20
  * - `NativeLauncher` — handing one native agent UI the foreground terminal
21
- * (`reserveTerminal`, `flushOutput`, `nativeLaunch`)
21
+ * (`reserveTerminal`, `flushOutput`, `notifyTerminal`, `nativeLaunch`)
22
22
  * - `Config` — shared execution config (`timeout`, `timeoutExec`, `timeoutFetch`,
23
23
  * `verbose`)
24
24
  *
@@ -37,7 +37,7 @@ export { asDuration, durationError, parseDuration } from "./duration.js";
37
37
  export type { ProcessExecOptions, ProcessOutcome } from "./apis.js";
38
38
  export { asFilesFatal, FILES_ERROR, FILES_ERROR_MESSAGE, FILES_FATAL, FILES_INVARIANT_MESSAGE, FILES_OPERATION_DENIED_MESSAGE, FILES_PROVIDER_UNAVAILABLE_MESSAGE, FILES_WRITE_SUCCESS, Files, FilesError, FilesInvariantError, FilesOperationDeniedError, FilesProviderUnavailableError, fileWriteFailure, fileWriteSuccess, filesFailure, isFilesFatal, parseFilesPhase, parseFilesReason, parseFileWriteFailure, parseFileWritePhase, parseFileWriteSuccess, parseFilesFailure, parseFilesFatal, } from "./files.js";
39
39
  export type { FilePathInput, FilesDeniableOperation, FilesErrorData, FilesFailureData, FilesFatalData, FilesFatalFailure, FilesHandler, FilesInvariantCategory, FilesOperation, FilesPhase, FilesReason, FileWriteFailureData, FileWriteInput, FileWritePhase, FileWriteSuccess, FileWriteTarget, GlobInput, } from "./files.js";
40
- export { flushOutput, installControlledLauncher, installForegroundLauncher, NATIVE_LAUNCHER_UNAVAILABLE, NativeLauncher, NativeLauncherUnavailableError, nativeLaunch, NO_TERMINAL, reserveTerminal, } from "./launcher.js";
40
+ export { flushOutput, installControlledLauncher, installForegroundLauncher, NATIVE_LAUNCHER_UNAVAILABLE, NativeLauncher, NativeLauncherUnavailableError, nativeLaunch, NO_TERMINAL, notifyTerminal, reserveTerminal, } from "./launcher.js";
41
41
  export type { ControlledLauncherOptions, NativeLauncherHandler, NativeLaunchOutcome, NativeLaunchRequest, } from "./launcher.js";
42
42
  export { hostFilesHandler, useHostFiles } from "./host-files.js";
43
43
  export type { HostFilesEvent, HostFilesObserver, HostFilesOptions } from "./host-files.js";