omgbase 0.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.
Files changed (80) hide show
  1. package/LICENSE +21 -0
  2. package/dist/src/cmd/_embed.d.ts +55 -0
  3. package/dist/src/cmd/_embed.js +102 -0
  4. package/dist/src/cmd/_mutate.d.ts +47 -0
  5. package/dist/src/cmd/_mutate.js +211 -0
  6. package/dist/src/cmd/_remote.d.ts +8 -0
  7. package/dist/src/cmd/_remote.js +61 -0
  8. package/dist/src/cmd/_source.d.ts +13 -0
  9. package/dist/src/cmd/_source.js +47 -0
  10. package/dist/src/cmd/admin.d.ts +6 -0
  11. package/dist/src/cmd/admin.js +289 -0
  12. package/dist/src/cmd/bootstrap.d.ts +3 -0
  13. package/dist/src/cmd/bootstrap.js +252 -0
  14. package/dist/src/cmd/cat.d.ts +2 -0
  15. package/dist/src/cmd/cat.js +80 -0
  16. package/dist/src/cmd/diff.d.ts +2 -0
  17. package/dist/src/cmd/diff.js +76 -0
  18. package/dist/src/cmd/docs.d.ts +6 -0
  19. package/dist/src/cmd/docs.js +154 -0
  20. package/dist/src/cmd/edit.d.ts +2 -0
  21. package/dist/src/cmd/edit.js +74 -0
  22. package/dist/src/cmd/find.d.ts +2 -0
  23. package/dist/src/cmd/find.js +98 -0
  24. package/dist/src/cmd/help.d.ts +2 -0
  25. package/dist/src/cmd/help.js +47 -0
  26. package/dist/src/cmd/hist.d.ts +2 -0
  27. package/dist/src/cmd/hist.js +58 -0
  28. package/dist/src/cmd/links.d.ts +2 -0
  29. package/dist/src/cmd/links.js +76 -0
  30. package/dist/src/cmd/log.d.ts +2 -0
  31. package/dist/src/cmd/log.js +109 -0
  32. package/dist/src/cmd/ls.d.ts +2 -0
  33. package/dist/src/cmd/ls.js +88 -0
  34. package/dist/src/cmd/mcp.d.ts +2 -0
  35. package/dist/src/cmd/mcp.js +192 -0
  36. package/dist/src/cmd/mutate.d.ts +10 -0
  37. package/dist/src/cmd/mutate.js +352 -0
  38. package/dist/src/cmd/node.d.ts +2 -0
  39. package/dist/src/cmd/node.js +66 -0
  40. package/dist/src/cmd/oqx.d.ts +2 -0
  41. package/dist/src/cmd/oqx.js +193 -0
  42. package/dist/src/cmd/outline.d.ts +2 -0
  43. package/dist/src/cmd/outline.js +87 -0
  44. package/dist/src/cmd/retarget.d.ts +2 -0
  45. package/dist/src/cmd/retarget.js +91 -0
  46. package/dist/src/cmd/run.d.ts +2 -0
  47. package/dist/src/cmd/run.js +135 -0
  48. package/dist/src/cmd/shell.d.ts +2 -0
  49. package/dist/src/cmd/shell.js +159 -0
  50. package/dist/src/cmd/show.d.ts +2 -0
  51. package/dist/src/cmd/show.js +107 -0
  52. package/dist/src/cmd/source.d.ts +2 -0
  53. package/dist/src/cmd/source.js +231 -0
  54. package/dist/src/cmd/status.d.ts +2 -0
  55. package/dist/src/cmd/status.js +95 -0
  56. package/dist/src/cmd/sync.d.ts +2 -0
  57. package/dist/src/cmd/sync.js +176 -0
  58. package/dist/src/cmd/update.d.ts +2 -0
  59. package/dist/src/cmd/update.js +100 -0
  60. package/dist/src/commands.d.ts +18 -0
  61. package/dist/src/commands.js +112 -0
  62. package/dist/src/context.d.ts +73 -0
  63. package/dist/src/context.js +80 -0
  64. package/dist/src/dispatch.d.ts +8 -0
  65. package/dist/src/dispatch.js +148 -0
  66. package/dist/src/main.d.ts +3 -0
  67. package/dist/src/main.js +67 -0
  68. package/dist/src/output.d.ts +60 -0
  69. package/dist/src/output.js +131 -0
  70. package/dist/src/render.d.ts +44 -0
  71. package/dist/src/render.js +116 -0
  72. package/dist/src/shell/refs.d.ts +37 -0
  73. package/dist/src/shell/refs.js +111 -0
  74. package/dist/src/shell/session.d.ts +71 -0
  75. package/dist/src/shell/session.js +317 -0
  76. package/dist/src/shell/tokenize.d.ts +3 -0
  77. package/dist/src/shell/tokenize.js +79 -0
  78. package/dist/src/style.d.ts +58 -0
  79. package/dist/src/style.js +159 -0
  80. package/package.json +63 -0
@@ -0,0 +1,131 @@
1
+ // Output contract + error rendering (11 §2.4, §4).
2
+ //
3
+ // Exit codes: 0 success (incl. truncated) · 1 typed engine error / conflict
4
+ // 2 CLI usage error (unknown flag, missing arg)
5
+ //
6
+ // Errors always go to stderr. Human form: `error[code]: message` + any
7
+ // current-truth payload pretty-printed. With --json: the typed error object as
8
+ // JSON on stderr, nothing on stdout.
9
+ export const EXIT_OK = 0;
10
+ export const EXIT_ERROR = 1;
11
+ export const EXIT_USAGE = 2;
12
+ /** A CLI-level usage error (bad flag, missing argument) → exit 2. An optional
13
+ * `hint` is a one-line pointer at the fix (e.g. "run 'omg --help' …"). */
14
+ export class CliUsageError extends Error {
15
+ hint;
16
+ constructor(message, hint) {
17
+ super(message);
18
+ this.hint = hint;
19
+ this.name = "CliUsageError";
20
+ }
21
+ }
22
+ export function renderHelp(cli, spec) {
23
+ const { io, style, prog } = cli;
24
+ io.out(` ${style.bold(spec.name)} — ${spec.summary}`);
25
+ const usages = Array.isArray(spec.usage) ? spec.usage : [spec.usage];
26
+ usages.forEach((u, i) => io.out(` ${style.dim(i === 0 ? "usage:" : " ")} ${prog} ${u}`));
27
+ const options = [...(spec.options ?? []), ["-h, --help", "show this help"]];
28
+ const width = Math.max(...options.map(([f]) => f.length));
29
+ io.out(` ${style.dim("options:")}`);
30
+ for (const [flag, desc] of options)
31
+ io.out(` ${style.accent(flag.padEnd(width))} ${desc}`);
32
+ if (spec.notes && spec.notes.length > 0) {
33
+ io.out("");
34
+ for (const n of spec.notes)
35
+ io.out(` ${n}`);
36
+ }
37
+ return EXIT_OK;
38
+ }
39
+ /**
40
+ * An engine-style typed error the CLI raises directly (mirrors core's
41
+ * EngineError body shape, 06 §5) — used for repo_not_found, ambiguous repo,
42
+ * etc., that originate in the CLI layer rather than the engine.
43
+ */
44
+ export class EngineErrorLike extends Error {
45
+ code;
46
+ extra;
47
+ constructor(code, message, extra = {}) {
48
+ super(message);
49
+ this.code = code;
50
+ this.extra = extra;
51
+ this.name = "EngineErrorLike";
52
+ }
53
+ body() {
54
+ return {
55
+ error: this.code,
56
+ message: this.message,
57
+ ...(this.extra.data !== undefined ? { data: this.extra.data } : {}),
58
+ retriable: this.extra.retriable ?? false,
59
+ };
60
+ }
61
+ }
62
+ /** Coerce any thrown value into a typed error body for rendering. */
63
+ function toBody(err) {
64
+ if (err instanceof EngineErrorLike) {
65
+ const b = err.body();
66
+ return {
67
+ code: b.error,
68
+ message: b.message,
69
+ ...(b.data !== undefined ? { data: b.data } : {}),
70
+ ...(err.extra.hint ? { hint: err.extra.hint } : {}),
71
+ };
72
+ }
73
+ // core EngineError / MutationError / FilterInvalid all carry a code + message
74
+ // (and often a body()); duck-type them.
75
+ const anyErr = err;
76
+ if (typeof anyErr?.body === "function") {
77
+ const b = anyErr.body();
78
+ return { code: b.error ?? b.code ?? "error", message: b.message ?? String(err), data: b.data };
79
+ }
80
+ if (anyErr?.code) {
81
+ return {
82
+ code: anyErr.code,
83
+ message: anyErr.message ?? String(err),
84
+ ...(anyErr.data !== undefined ? { data: anyErr.data } : {}),
85
+ ...(anyErr.hint ? { hint: anyErr.hint } : {}),
86
+ };
87
+ }
88
+ return { code: "error", message: anyErr?.message ?? String(err) };
89
+ }
90
+ /**
91
+ * Render a thrown error to stderr and return the process exit code. `json`
92
+ * selects machine output (typed object); otherwise the human form with any
93
+ * current-truth payload pretty-printed.
94
+ */
95
+ export function renderError(err, io, style, json) {
96
+ if (err instanceof CliUsageError) {
97
+ if (json)
98
+ io.err(JSON.stringify({ error: "usage", message: err.message, ...(err.hint ? { hint: err.hint } : {}), retriable: false }));
99
+ else {
100
+ io.err(`${style.err("usage")}: ${err.message}`);
101
+ if (err.hint)
102
+ io.err(style.dim(` hint: ${err.hint}`));
103
+ }
104
+ return EXIT_USAGE;
105
+ }
106
+ const body = toBody(err);
107
+ if (json) {
108
+ io.err(JSON.stringify({ error: body.code, message: body.message, ...(body.data !== undefined ? { data: body.data } : {}), retriable: false }));
109
+ return EXIT_ERROR;
110
+ }
111
+ io.err(`${style.err(`error[${body.code}]`)}: ${body.message}`);
112
+ if (body.hint)
113
+ io.err(style.dim(` hint: ${body.hint}`));
114
+ // Conflict objects carry current truth (04 §4) — print all of it; the retry
115
+ // is built from it.
116
+ if (body.data !== undefined && body.data !== null) {
117
+ io.err(style.dim(indent(JSON.stringify(body.data, null, 2), " ")));
118
+ }
119
+ return EXIT_ERROR;
120
+ }
121
+ function indent(s, pad) {
122
+ return s
123
+ .split("\n")
124
+ .map((l) => pad + l)
125
+ .join("\n");
126
+ }
127
+ /** Loud truncation footer to stderr (§4.4). Exit code stays 0. */
128
+ export function truncationFooter(io, style, cursor) {
129
+ io.err(style.dim(`… truncated; continue with --cursor ${cursor}`));
130
+ }
131
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1,44 @@
1
+ import { Style, type Glyphs, type Tier } from "./style.js";
2
+ /** Visible width of a string, ignoring ANSI SGR sequences. */
3
+ export declare function visibleWidth(s: string): number;
4
+ export declare function stripAnsi(s: string): string;
5
+ export interface Column {
6
+ /** "left" (default) or "right" alignment. */
7
+ align?: "left" | "right";
8
+ }
9
+ /** Align a matrix of already-styled cells into padded columns joined by gap. */
10
+ export declare function columns(rows: string[][], cols?: Column[], gap?: string): string[];
11
+ export declare class Renderer {
12
+ readonly style: Style;
13
+ readonly g: Glyphs;
14
+ readonly tier: Tier;
15
+ constructor(style: Style);
16
+ /** The branded wordmark line: gradient "omgbase" + accent arrow + subject. */
17
+ wordmark(subject?: string): string;
18
+ /** A full-width gradient underline for the header (rich only; else a rule). */
19
+ rule(width?: number): string;
20
+ /** A colored status dot + label, e.g. ● live / ○ none. */
21
+ statusDot(state: "live" | "none" | "ok" | "warn" | "err", label: string): string;
22
+ /** Glyph for a node/block type (used in outlines and hit lists). */
23
+ typeGlyph(type: string): string;
24
+ /** id (dim) paired with locator (accent) — the §4.2 pairing. */
25
+ idLocator(id: string, locator: string): string;
26
+ }
27
+ export interface IO {
28
+ out(s: string): void;
29
+ err(s: string): void;
30
+ readonly stdoutTTY: boolean;
31
+ readonly stderrTTY: boolean;
32
+ }
33
+ export declare const processIO: IO;
34
+ /** Collecting IO for tests: captures out/err lines. */
35
+ export declare class CaptureIO implements IO {
36
+ outLines: string[];
37
+ errLines: string[];
38
+ stdoutTTY: boolean;
39
+ stderrTTY: boolean;
40
+ out(s: string): void;
41
+ err(s: string): void;
42
+ get stdout(): string;
43
+ get stderr(): string;
44
+ }
@@ -0,0 +1,116 @@
1
+ import { Style, glyphs } from "./style.js";
2
+ // Human-facing renderer (11 §4). Columns, the branded header/box, status lines,
3
+ // hit lists — all TTY-only pizzazz. Width math strips ANSI so colored cells
4
+ // still align. Nothing here touches the machine paths (--json/--jsonl/--ids),
5
+ // which emit library objects verbatim from the command layer.
6
+ const ANSI_RE = /\x1b\[[0-9;]*m/g;
7
+ /** Visible width of a string, ignoring ANSI SGR sequences. */
8
+ export function visibleWidth(s) {
9
+ return stripAnsi(s).length;
10
+ }
11
+ export function stripAnsi(s) {
12
+ return s.replace(ANSI_RE, "");
13
+ }
14
+ function padEndVisible(s, width) {
15
+ const pad = width - visibleWidth(s);
16
+ return pad > 0 ? s + " ".repeat(pad) : s;
17
+ }
18
+ function padStartVisible(s, width) {
19
+ const pad = width - visibleWidth(s);
20
+ return pad > 0 ? " ".repeat(pad) + s : s;
21
+ }
22
+ /** Align a matrix of already-styled cells into padded columns joined by gap. */
23
+ export function columns(rows, cols = [], gap = " ") {
24
+ const widths = [];
25
+ for (const row of rows) {
26
+ row.forEach((cell, i) => {
27
+ widths[i] = Math.max(widths[i] ?? 0, visibleWidth(cell));
28
+ });
29
+ }
30
+ return rows.map((row) => row
31
+ .map((cell, i) => {
32
+ const w = widths[i] ?? 0;
33
+ // Don't pad the final column (avoids trailing whitespace).
34
+ if (i === row.length - 1)
35
+ return cell;
36
+ return (cols[i]?.align === "right" ? padStartVisible : padEndVisible)(cell, w);
37
+ })
38
+ .join(gap)
39
+ .replace(/\s+$/, ""));
40
+ }
41
+ export class Renderer {
42
+ style;
43
+ g;
44
+ tier;
45
+ constructor(style) {
46
+ this.style = style;
47
+ this.tier = style.tier;
48
+ this.g = glyphs(style.tier);
49
+ }
50
+ /** The branded wordmark line: gradient "omgbase" + accent arrow + subject. */
51
+ wordmark(subject) {
52
+ const mark = this.style.gradient("omgbase");
53
+ if (!subject)
54
+ return ` ${mark}`;
55
+ return ` ${mark} ${this.style.dim(this.g.arrow)} ${this.style.bold(subject)}`;
56
+ }
57
+ /** A full-width gradient underline for the header (rich only; else a rule). */
58
+ rule(width = 40) {
59
+ return " " + this.style.gradientBar(width);
60
+ }
61
+ /** A colored status dot + label, e.g. ● live / ○ none. */
62
+ statusDot(state, label) {
63
+ switch (state) {
64
+ case "live":
65
+ return `${this.style.ok(this.g.live)} ${label}`;
66
+ case "none":
67
+ return `${this.style.dim(this.g.dead)} ${label}`;
68
+ case "ok":
69
+ return `${this.style.ok(this.g.ok)} ${label}`;
70
+ case "warn":
71
+ return `${this.style.warn(this.g.warn)} ${label}`;
72
+ case "err":
73
+ return `${this.style.err(this.g.err)} ${label}`;
74
+ }
75
+ }
76
+ /** Glyph for a node/block type (used in outlines and hit lists). */
77
+ typeGlyph(type) {
78
+ if (type === "heading")
79
+ return this.style.accent(this.g.heading);
80
+ if (type === "task")
81
+ return this.g.taskOpen;
82
+ if (type.startsWith("doc"))
83
+ return this.style.path(this.g.doc);
84
+ return this.style.dim(this.g.block);
85
+ }
86
+ /** id (dim) paired with locator (accent) — the §4.2 pairing. */
87
+ idLocator(id, locator) {
88
+ return `${this.style.id(id)} ${this.style.accent(locator)}`;
89
+ }
90
+ }
91
+ export const processIO = {
92
+ out: (s) => process.stdout.write(s.endsWith("\n") ? s : s + "\n"),
93
+ err: (s) => process.stderr.write(s.endsWith("\n") ? s : s + "\n"),
94
+ stdoutTTY: Boolean(process.stdout.isTTY),
95
+ stderrTTY: Boolean(process.stderr.isTTY),
96
+ };
97
+ /** Collecting IO for tests: captures out/err lines. */
98
+ export class CaptureIO {
99
+ outLines = [];
100
+ errLines = [];
101
+ stdoutTTY = false;
102
+ stderrTTY = false;
103
+ out(s) {
104
+ this.outLines.push(s);
105
+ }
106
+ err(s) {
107
+ this.errLines.push(s);
108
+ }
109
+ get stdout() {
110
+ return this.outLines.join("\n");
111
+ }
112
+ get stderr() {
113
+ return this.errLines.join("\n");
114
+ }
115
+ }
116
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1,37 @@
1
+ export declare class RefError extends Error {
2
+ }
3
+ /** A selectable item within a displayed collection or a bound collection. */
4
+ export interface Row {
5
+ /** The argv string this row substitutes to (an id, locator, path, or scalar). */
6
+ ref: string;
7
+ /** Human label for `bindings` / frame listings. */
8
+ label: string;
9
+ /** The underlying typed value (for `.field` access). */
10
+ value: unknown;
11
+ }
12
+ /** A captured command result: the whole typed value plus any selectable rows. */
13
+ export interface Captured {
14
+ value: unknown;
15
+ /** Non-null ⇒ this result is a selectable collection (replaces the frame). */
16
+ rows: Row[] | null;
17
+ }
18
+ export interface ParsedRef {
19
+ base: string;
20
+ index?: number;
21
+ field?: string;
22
+ }
23
+ /** Parse a whole-token reference; null if the token isn't a reference. */
24
+ export declare function parseRef(token: string): ParsedRef | null;
25
+ /**
26
+ * Derive the selectable rows of a captured value. Returns null when the value
27
+ * is a card / scalar / text (no collection) — the caller then leaves the
28
+ * numbered frame intact (the note's "showing one thing shouldn't destroy the
29
+ * frame"). Returns an array (possibly empty) when the value IS a collection.
30
+ */
31
+ export declare function deriveRows(value: unknown): Row[] | null;
32
+ /**
33
+ * Coerce a resolved value to a single argv string. Entities collapse to their
34
+ * id/locator; scalars stringify; a bare collection is an error (the caller must
35
+ * pick a row with `[i]`) — the shell never flattens a collection into one arg.
36
+ */
37
+ export declare function coerce(value: unknown): string;
@@ -0,0 +1,111 @@
1
+ // Session references (11 shell). The shell stores typed command results and
2
+ // dereferences them; it does NOT filter/map/traverse — that stays OQX's job.
3
+ //
4
+ // Three reference roots, all written with `@` (OQX already owns `$…`):
5
+ // @N row N (1-based) of the most recent displayed collection frame
6
+ // @_ the previous command's typed result
7
+ // @name a named binding (`@name = …`)
8
+ // Each may carry a shallow tail: an optional `[i]` (1-based collection index)
9
+ // then an optional `.field`. That is the whole grammar — deeper access is a
10
+ // signal to use OQX instead.
11
+ export class RefError extends Error {
12
+ }
13
+ const REF_RE = /^@(\d+|_|[A-Za-z][\w-]*)(?:\[(\d+)\])?(?:\.([A-Za-z_]\w*))?$/;
14
+ /** Parse a whole-token reference; null if the token isn't a reference. */
15
+ export function parseRef(token) {
16
+ if (!token.startsWith("@"))
17
+ return null;
18
+ const m = REF_RE.exec(token);
19
+ if (!m)
20
+ throw new RefError(`bad reference '${token}' (use @N, @_, @name, optional [i] and .field)`);
21
+ const out = { base: m[1] };
22
+ if (m[2] !== undefined)
23
+ out.index = Number(m[2]);
24
+ if (m[3] !== undefined)
25
+ out.field = m[3];
26
+ return out;
27
+ }
28
+ /**
29
+ * Derive the selectable rows of a captured value. Returns null when the value
30
+ * is a card / scalar / text (no collection) — the caller then leaves the
31
+ * numbered frame intact (the note's "showing one thing shouldn't destroy the
32
+ * frame"). Returns an array (possibly empty) when the value IS a collection.
33
+ */
34
+ export function deriveRows(value) {
35
+ if (Array.isArray(value))
36
+ return value.map(rowOf);
37
+ if (value && typeof value === "object") {
38
+ const o = value;
39
+ if (Array.isArray(o.hits))
40
+ return o.hits.map(rowOf); // query/oqx
41
+ if (Array.isArray(o.digests))
42
+ return o.digests.map(rowOf); // log
43
+ if (Array.isArray(o.results) && Array.isArray(o.revisions)) {
44
+ // ApplyResult: the minted/affected ids, flattened (one row per id).
45
+ const ids = [];
46
+ for (const r of o.results) {
47
+ if (Array.isArray(r.ids))
48
+ for (const id of r.ids)
49
+ if (typeof id === "string")
50
+ ids.push(id);
51
+ }
52
+ return ids.map((id) => ({ ref: id, label: id, value: id }));
53
+ }
54
+ if (Array.isArray(o.in) || Array.isArray(o.out)) {
55
+ // links: both directions, each edge's far node is the selectable ref.
56
+ const edges = [...(o.out ?? []), ...(o.in ?? [])];
57
+ return edges.map(rowOf);
58
+ }
59
+ }
60
+ return null;
61
+ }
62
+ function rowOf(el) {
63
+ if (typeof el === "string")
64
+ return { ref: el, label: el, value: el };
65
+ if (el && typeof el === "object") {
66
+ const o = el;
67
+ const ref = firstString(o, ["id", "node", "block", "locator", "path"]);
68
+ const label = firstString(o, ["path", "locator", "name", "id", "node"]) ?? ref ?? preview(o);
69
+ return { ref: ref ?? label ?? "", label: label ?? "", value: el };
70
+ }
71
+ const s = String(el);
72
+ return { ref: s, label: s, value: el };
73
+ }
74
+ function firstString(o, keys) {
75
+ for (const k of keys)
76
+ if (typeof o[k] === "string")
77
+ return o[k];
78
+ return undefined;
79
+ }
80
+ function preview(o) {
81
+ const s = JSON.stringify(o);
82
+ return s.length > 60 ? s.slice(0, 57) + "…" : s;
83
+ }
84
+ /**
85
+ * Coerce a resolved value to a single argv string. Entities collapse to their
86
+ * id/locator; scalars stringify; a bare collection is an error (the caller must
87
+ * pick a row with `[i]`) — the shell never flattens a collection into one arg.
88
+ */
89
+ export function coerce(value) {
90
+ if (typeof value === "string")
91
+ return value;
92
+ if (typeof value === "number" || typeof value === "boolean")
93
+ return String(value);
94
+ if (value == null)
95
+ throw new RefError("reference is empty");
96
+ if (Array.isArray(value)) {
97
+ throw new RefError(`reference is a collection of ${value.length}; select one with [i]`);
98
+ }
99
+ if (typeof value === "object") {
100
+ const o = value;
101
+ const ref = firstString(o, ["id", "node", "block", "locator", "path"]);
102
+ if (ref)
103
+ return ref;
104
+ // A collection-shaped result object (e.g. {hits:[…]}) can't be one arg.
105
+ if (deriveRows(value))
106
+ throw new RefError("reference is a collection; select one with [i]");
107
+ throw new RefError("reference has no id/locator to use as an argument");
108
+ }
109
+ throw new RefError("reference is not usable as an argument");
110
+ }
111
+ //# sourceMappingURL=refs.js.map
@@ -0,0 +1,71 @@
1
+ import type { Workspace } from "@omgbase/core";
2
+ import type { IO } from "../render.js";
3
+ import { EXIT_OK, EXIT_ERROR } from "../output.js";
4
+ export interface ShellSessionOptions {
5
+ /** The shared local workspace. Omitted in remote (`--server`) mode: every line
6
+ * routes over MCP and never touches a local store. */
7
+ workspace?: Workspace;
8
+ cwd: string;
9
+ io: IO;
10
+ /** Force plain styling for the shell's own notices (matches the command tier). */
11
+ noColor?: boolean;
12
+ /** Remote engine address (`--server <cmd|url>`): threaded into every line so
13
+ * each command runs against the remote engine and shares one connection. */
14
+ server?: string;
15
+ /** Extra HTTP headers (`-H`) for an http(s) `--server`: threaded alongside it. */
16
+ headers?: string[];
17
+ }
18
+ export declare class ShellSession {
19
+ private readonly workspace;
20
+ private readonly cwd;
21
+ private readonly io;
22
+ private readonly style;
23
+ private readonly server;
24
+ private readonly headers;
25
+ private readonly bindings;
26
+ private frame;
27
+ private last;
28
+ /** Set by `exit`/`quit`; the interactive loop watches this. */
29
+ exited: boolean;
30
+ constructor(opts: ShellSessionOptions);
31
+ /** Execute one input line. Returns an exit code (0 ok, 1 error, 2 usage). */
32
+ exec(line: string): Promise<number>;
33
+ /**
34
+ * `@name = <command | @ref>` — bind a snapshot of a result under `name`.
35
+ * A command runs quietly (stdout suppressed); a bare `@ref` copies its value.
36
+ * The target must be a plain name (no `[i]`/`.field`, not `@_`/`@N`).
37
+ */
38
+ private doAssign;
39
+ private doUnset;
40
+ private doBindings;
41
+ private doShellHelp;
42
+ /** A normal omg command line: substitute refs, dispatch, record the result. */
43
+ private runLine;
44
+ /**
45
+ * Build a per-line Cli over the shared Workspace and run the command through
46
+ * the same path as a one-shot invocation (freshness sweep + dispatch + error
47
+ * mapping). `sink` receives the command's typed result; `quiet` drops stdout
48
+ * (used by `let`, which snapshots rather than displays).
49
+ */
50
+ private dispatch;
51
+ /** Update @_ and, when the result is a collection, replace the numbered frame. */
52
+ private record;
53
+ /** Inspect a bare `@ref` line: print it and, if a collection, make it the frame. */
54
+ private inspect;
55
+ /** Replace whole-token `@refs` with their coerced argv strings. */
56
+ private substitute;
57
+ /**
58
+ * Resolve a reference token to its typed value plus, when known, a direct
59
+ * argv-usable id/locator. Coercion is deferred to the caller (substitution)
60
+ * so that inspecting a bare collection reference does not error.
61
+ */
62
+ resolveRef(token: string): {
63
+ value: unknown;
64
+ ref?: string;
65
+ };
66
+ private summary;
67
+ private usage;
68
+ /** An IO that drops stdout (data) but forwards stderr (diagnostics). */
69
+ private quietIO;
70
+ }
71
+ export { EXIT_OK, EXIT_ERROR };