@dolusoft/command-console-core 1.0.1 → 1.1.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.
@@ -1,7 +1,7 @@
1
- import type { CommandResponse, CommandSpec, ConsoleEntry, ContextFrame } from '@dolusoft/command-protocol';
1
+ import type { Actor, CommandOutcome, CommandResponse, CommandSpec, ConsoleEntry, ContextFrame } from '@dolusoft/command-protocol';
2
2
  import type { KeyInput } from '../../shared/keys.js';
3
3
  import type { Updater } from '../../store/action.js';
4
- import type { BeforeRunResult, CommandDefinition, RunInfo } from '../dispatch/dispatch.types.js';
4
+ import type { BeforeRunResult, CommandDefinition, ConsoleGate, RunInfo } from '../dispatch/dispatch.types.js';
5
5
  /** The live input line. */
6
6
  export interface InputState {
7
7
  value: string;
@@ -154,7 +154,28 @@ export interface ConsoleOptions<TFeatures extends Partial<OptionalFeatures> = {}
154
154
  recallLimit?: number;
155
155
  /** Whether a line is recorded (recall feature); default every line. */
156
156
  shouldRecord?: (line: string) => boolean;
157
+ /**
158
+ * Sends the lines of commands with `input` and `danger` as envelopes and
159
+ * runs them from their echo (ADR 0012); fixed for the life of the console.
160
+ */
161
+ gate?: ConsoleGate;
162
+ /** The view instance a typed line targets, read when the line ends. */
163
+ activeView?: () => string | undefined;
164
+ /** How long an envelope waits for its echo, in ms; default 5000. */
165
+ echoTimeoutMs?: number;
166
+ /** Makes envelope ids; default `crypto.randomUUID()`. */
167
+ createEnvelopeId?: () => string;
157
168
  }
169
+ /** What `request()` runs: a command and its input, or a line. */
170
+ export type RequestInput = {
171
+ command: string;
172
+ args: Record<string, unknown>;
173
+ view?: string;
174
+ actor: Actor;
175
+ } | {
176
+ line: string;
177
+ actor: Actor;
178
+ };
158
179
  /** The methods every console has. */
159
180
  export interface CoreConsoleAPI<TFeatures extends Partial<OptionalFeatures> = {}> {
160
181
  /** The committed state; the same object until the next change. */
@@ -203,6 +224,11 @@ export interface CoreConsoleAPI<TFeatures extends Partial<OptionalFeatures> = {}
203
224
  run(line: string): Promise<boolean>;
204
225
  /** Interrupts the running command, else cancels the live line. */
205
226
  cancel(): void;
227
+ /**
228
+ * Runs a command for a caller other than the user's Enter (an agent).
229
+ * Never rejects: every refusal or failure is an `error` outcome.
230
+ */
231
+ request(input: RequestInput): Promise<CommandOutcome>;
206
232
  /** Applies the key map; `true` when the key was handled. */
207
233
  handleKey(input: KeyInput): boolean;
208
234
  }
@@ -0,0 +1,24 @@
1
+ import type { ErrorCode } from '@dolusoft/command-protocol';
2
+ /**
3
+ * The codes a command's `run` may end with through a `CommandError`. The
4
+ * other codes belong to the core (`busy`, `timeout`, `id-conflict`, …); a
5
+ * `CommandError` that carries one gives `failed`.
6
+ */
7
+ export type CommandErrorCode = Extract<ErrorCode, 'target-not-found' | 'invalid-args' | 'failed'>;
8
+ /**
9
+ * Thrown (or rejected) by a command's `run` to end the run with `code`: the
10
+ * run fails as with any error (`onError`, the error entry), and the outcome a
11
+ * `request()` resolves is `{ status: 'error', code }`.
12
+ */
13
+ export declare class CommandError extends Error {
14
+ /** The code the run's outcome carries. */
15
+ readonly code: CommandErrorCode;
16
+ constructor(code: CommandErrorCode, message?: string, options?: ErrorOptions);
17
+ }
18
+ /**
19
+ * The outcome code of an error a command's `run` threw: a `CommandError`'s
20
+ * code when a command may give it, else `failed` (C-86). The error is known
21
+ * by its `name`, not by `instanceof`: a command built against a second copy
22
+ * of the core throws a `CommandError` of another class.
23
+ */
24
+ export declare const commandErrorCode: (error: unknown) => CommandErrorCode;
@@ -1,4 +1,4 @@
1
- import type { CommandResponse, CommandSpec, ContextFrame, OutputBlock, OutputEntry } from '@dolusoft/command-protocol';
1
+ import type { CommandResponse, CommandSpec, ContextFrame, Envelope, JsonValue, OutputBlock, OutputEntry } from '@dolusoft/command-protocol';
2
2
  /**
3
3
  * What `beforeRun` returns: `undefined` goes on to the command's `run`;
4
4
  * `false` ends the run silently; a response ends the run as if the command
@@ -36,6 +36,12 @@ export interface CommandDefinition extends CommandSpec {
36
36
  * Called only for safe positions (README: Completion).
37
37
  */
38
38
  complete?(request: CompletionRequest): CompletionResult;
39
+ /**
40
+ * Maps the validated input of a command with `input` before it is sent or
41
+ * run (a relative time made absolute). Pure; its result is checked again
42
+ * against the schema.
43
+ */
44
+ normalize?(input: Record<string, JsonValue>): Record<string, JsonValue>;
39
45
  }
40
46
  /** The parsed line a command runs with. */
41
47
  export interface CommandRequest {
@@ -51,6 +57,27 @@ export interface CommandRequest {
51
57
  line: string;
52
58
  /** The context frames when the run started, bottom → top, root excluded. */
53
59
  context: ContextFrame[];
60
+ /**
61
+ * The validated, normalized input of a command with `input`; `args`, `rest`
62
+ * and `line` then come from its canonical line.
63
+ */
64
+ input?: Record<string, JsonValue>;
65
+ /** The view instance the line targets (`activeView()` or the request's). */
66
+ view?: string;
67
+ }
68
+ /**
69
+ * What the console sends envelopes through (ADR 0012). The consumer's
70
+ * transport implements it; the core never touches the network.
71
+ */
72
+ export interface ConsoleGate {
73
+ /** The id of this tab, the same for the life of the page. */
74
+ tab: string;
75
+ /** Sends an envelope; a rejection ends the operation as `connection-lost`. */
76
+ send(envelope: Envelope): Promise<void>;
77
+ /** Calls `listener` with every value the transport receives. */
78
+ subscribe(listener: (raw: unknown) => void): () => void;
79
+ /** Calls `fn` once after `ms`; returns the function that cancels it. */
80
+ schedule(ms: number, fn: () => void): () => void;
54
81
  }
55
82
  /** The handle a running command gets. */
56
83
  export interface RunContext {
@@ -1,10 +1,11 @@
1
- import type { CommandResponse, CommandSpec, OutputBlock } from '@dolusoft/command-protocol';
1
+ import { type CommandResponse, type CommandSpec, type OutputBlock } from '@dolusoft/command-protocol';
2
2
  import type { CommandDefinition, CommandReturn } from './dispatch.types.js';
3
3
  /**
4
4
  * Validates the commands (core README: Options, C-56): names and aliases are
5
5
  * non-empty, without whitespace or quotes, unique across every name and alias;
6
- * `fromArg` is a non-negative integer; `run` is a function. Throws on the
7
- * first violation.
6
+ * `fromArg` is a non-negative integer; `run` is a function; `input` is an
7
+ * input schema, `danger` a known value and `normalize` a function (C-76).
8
+ * Throws on the first violation.
8
9
  */
9
10
  export declare const validateCommands: (commands: unknown) => void;
10
11
  /** The JSON spec of a command, without its functions (`getCommands`). */
@@ -0,0 +1,23 @@
1
+ import type { CommandDefinition } from './dispatch.types.js';
2
+ import type { AnyConsoleOptions } from '../console/console.types.js';
3
+ /** Whether two JSON values are equal, objects compared by their keys. */
4
+ export declare const sameJson: (a: unknown, b: unknown) => boolean;
5
+ /** Remembers `id` among the newest `closedLimit` closed ids. */
6
+ export declare const rememberClosed: (closed: Set<string>, id: string) => void;
7
+ /** `summary` cut to `summaryLimit` code points; `undefined` unless a string. */
8
+ export declare const cutSummary: (summary: unknown) => string | undefined;
9
+ /**
10
+ * What makes envelope ids: `createEnvelopeId`, else the page's UUID function.
11
+ * Throws when a gate is given and neither exists (C-78).
12
+ */
13
+ export declare const envelopeIds: (options: Pick<AnyConsoleOptions, "gate" | "createEnvelopeId">) => (() => string) | undefined;
14
+ /**
15
+ * Checks the gate options at creation and on every `setOptions` (C-78):
16
+ * envelope ids can be made, and `echoTimeoutMs` is a finite number above 0.
17
+ */
18
+ export declare const checkGateOptions: (options: Pick<AnyConsoleOptions, "gate" | "createEnvelopeId" | "echoTimeoutMs">) => void;
19
+ /**
20
+ * Whether a command can travel in an envelope: it has `input` and `danger`
21
+ * and no `sensitive` (C-79).
22
+ */
23
+ export declare const describedCommand: (command: CommandDefinition) => boolean;
@@ -0,0 +1,34 @@
1
+ import type { JsonValue } from '@dolusoft/command-protocol';
2
+ import type { CoreConsoleAPI } from '../core/console/console.types.js';
3
+ /** The hints a tool carries (WebMCP `ToolAnnotations`). */
4
+ export interface AgentToolAnnotations {
5
+ /** The tool does not change the application. */
6
+ readOnlyHint?: boolean;
7
+ /** The result may hold text the agent should not take as instructions. */
8
+ untrustedContentHint?: boolean;
9
+ }
10
+ /** One tool, as a WebMCP `ModelContextTool` takes it. */
11
+ export interface AgentTool {
12
+ /** `context`, `help` or `run`. */
13
+ name: string;
14
+ /** What the tool does, for the agent. */
15
+ description: string;
16
+ /** A JSON Schema of the tool's input. */
17
+ inputSchema: {
18
+ [key: string]: JsonValue;
19
+ };
20
+ /** The tool's hints. */
21
+ annotations: AgentToolAnnotations;
22
+ /** Never rejects: a failure is an `error` outcome. */
23
+ execute(input: unknown): Promise<JsonValue>;
24
+ }
25
+ /** What `agentTools` needs besides the console. */
26
+ export interface AgentToolsOptions {
27
+ /** What the `context` tool returns: the tab, its views, the active view. */
28
+ context: () => JsonValue | Promise<JsonValue>;
29
+ }
30
+ /**
31
+ * The `context`, `help` and `run` tools of `console` (C-83). `run` calls
32
+ * `console.request` as `external-agent`, so only `read` commands run.
33
+ */
34
+ export declare function agentTools(console: Pick<CoreConsoleAPI, 'getCommands' | 'request'>, options: AgentToolsOptions): [AgentTool, AgentTool, AgentTool];
@@ -1,8 +1,12 @@
1
1
  export { consoleFeatures, createConsole } from './helpers/consoleFeatures.js';
2
+ export { agentTools } from './helpers/agentTools.js';
3
+ export { CommandError } from './core/dispatch/commandError.js';
4
+ export type { CommandErrorCode } from './core/dispatch/commandError.js';
5
+ export type { AgentTool, AgentToolAnnotations, AgentToolsOptions } from './helpers/agentTools.js';
2
6
  export { contextFeature } from './features/context/contextFeature.js';
3
7
  export { recallFeature } from './features/recall/recallFeature.js';
4
8
  export { completionFeature } from './features/completion/completionFeature.js';
5
- export type { CompletionAPI, CompletionFeature, CompletionSession, Console, ConsoleOptions, ConsoleState, ContextAPI, ContextFeature, ControllableState, CoreConsoleAPI, FeatureAPIsOf, InputState, OptionalFeatures, RecallAPI, RecallFeature, RunningCommand } from './core/console/console.types.js';
6
- export type { BeforeRunResult, CommandDefinition, CommandRequest, CommandReturn, CompletionRequest, CompletionResult, RunContext, RunInfo } from './core/dispatch/dispatch.types.js';
9
+ export type { CompletionAPI, CompletionFeature, CompletionSession, Console, ConsoleOptions, ConsoleState, ContextAPI, ContextFeature, ControllableState, CoreConsoleAPI, FeatureAPIsOf, InputState, OptionalFeatures, RecallAPI, RecallFeature, RequestInput, RunningCommand } from './core/console/console.types.js';
10
+ export type { BeforeRunResult, CommandDefinition, CommandRequest, CommandReturn, CompletionRequest, CompletionResult, ConsoleGate, RunContext, RunInfo } from './core/dispatch/dispatch.types.js';
7
11
  export type { KeyInput } from './shared/keys.js';
8
12
  export type { Updater } from './store/action.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dolusoft/command-console-core",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "The engine of a headless command console: createConsole, its features (recall, completion, context) and redaction of sensitive lines. No framework.",
5
5
  "private": false,
6
6
  "type": "module",
@@ -32,7 +32,7 @@
32
32
  "homepage": "https://github.com/dolusoft/command-console#readme",
33
33
  "license": "MIT",
34
34
  "dependencies": {
35
- "@dolusoft/command-protocol": "1.0.1"
35
+ "@dolusoft/command-protocol": "1.1.0"
36
36
  },
37
37
  "scripts": {
38
38
  "build": "vite build && tsc -p tsconfig.build.json && node ../../scripts/emit-type-extensions.mjs dist/types"