@corenel/term 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.
@@ -0,0 +1,47 @@
1
+ // src/commands.ts
2
+ var TERM_COMMANDS = [
3
+ { name: "help", summary: "what you can type here" },
4
+ { name: "tools", summary: "what the agent can do, and what it can change" },
5
+ { name: "expand", args: "<#n>", summary: "re-print a tool result in full" },
6
+ { name: "resume", args: "[id]", summary: "reopen an earlier conversation" },
7
+ { name: "clear", summary: "forget the conversation" },
8
+ { name: "exit", summary: "leave" }
9
+ ];
10
+ var ALIASES = { quit: "exit" };
11
+ function parseCommand(line) {
12
+ const t = line.trim();
13
+ if (!t.startsWith("/")) return null;
14
+ const [wordRaw, ...rest] = t.slice(1).split(/\s+/);
15
+ const word = ALIASES[wordRaw.toLowerCase()] ?? wordRaw.toLowerCase();
16
+ const arg = rest.join(" ").trim();
17
+ switch (word) {
18
+ case "help":
19
+ return { cmd: "help" };
20
+ case "tools":
21
+ return { cmd: "tools" };
22
+ case "clear":
23
+ return { cmd: "clear" };
24
+ case "exit":
25
+ return { cmd: "exit" };
26
+ case "expand": {
27
+ const m = /^#?(\d+)$/.exec(arg);
28
+ return m ? { cmd: "expand", ord: Number(m[1]) } : { cmd: "expand" };
29
+ }
30
+ case "resume":
31
+ return arg ? { cmd: "resume", id: arg } : { cmd: "resume" };
32
+ default:
33
+ return null;
34
+ }
35
+ }
36
+ function filterCommands(input) {
37
+ const t = input.trim();
38
+ if (!t.startsWith("/")) return [];
39
+ const prefix = t.slice(1).split(/\s+/)[0].toLowerCase();
40
+ return TERM_COMMANDS.filter((c) => c.name.startsWith(prefix));
41
+ }
42
+
43
+ export {
44
+ TERM_COMMANDS,
45
+ parseCommand,
46
+ filterCommands
47
+ };
@@ -0,0 +1,40 @@
1
+ // src/describe.ts
2
+ var PREVIEW_LINES = 6;
3
+ var PREVIEW_LINES_ERROR = 12;
4
+ var SUBJECT_WIDTH = 68;
5
+ function describeToolCall(_name, args) {
6
+ const a = args ?? {};
7
+ const raw = a.path ?? a.file ?? a.command ?? a.cmd ?? a.query ?? a.url;
8
+ const pattern = typeof a.pattern === "string" ? `/${a.pattern}/` : "";
9
+ const text = typeof raw === "string" ? raw : pattern;
10
+ if (!text) return "";
11
+ const one = text.replace(/\s+/g, " ").trim();
12
+ return one.length > SUBJECT_WIDTH ? `${one.slice(0, SUBJECT_WIDTH - 1)}\u2026` : one;
13
+ }
14
+ function capPreview(result, isError) {
15
+ const lines = result.split("\n").map((l) => l.replace(/\s+$/, ""));
16
+ while (lines.length && !lines[lines.length - 1].trim()) lines.pop();
17
+ while (lines.length && !lines[0].trim()) lines.shift();
18
+ if (!lines.length) return [];
19
+ const cap = isError ? PREVIEW_LINES_ERROR : PREVIEW_LINES;
20
+ if (lines.length <= cap) return lines;
21
+ const dropped = lines.length - cap;
22
+ return [...lines.slice(0, cap), `\u2026 ${dropped} more line${dropped === 1 ? "" : "s"}`];
23
+ }
24
+ function formatTools(tools) {
25
+ if (!tools.length) return "No tools are available.";
26
+ const w = Math.max(...tools.map((t) => t.name.length));
27
+ const line = (t) => ` ${t.name.padEnd(w)} ${t.mutates ? "*" : " "} ${t.means ?? t.description.split(". ")[0]}`;
28
+ return [
29
+ `${tools.length} tools available (* = can change things, and will ask first):`,
30
+ ...[...tools].sort((a, b) => a.name.localeCompare(b.name)).map(line)
31
+ ].join("\n");
32
+ }
33
+
34
+ export {
35
+ PREVIEW_LINES,
36
+ PREVIEW_LINES_ERROR,
37
+ describeToolCall,
38
+ capPreview,
39
+ formatTools
40
+ };
@@ -0,0 +1,25 @@
1
+ export interface TermCommand {
2
+ name: string;
3
+ args?: string;
4
+ summary: string;
5
+ }
6
+ export declare const TERM_COMMANDS: TermCommand[];
7
+ export type ParsedCommand = {
8
+ cmd: 'help';
9
+ } | {
10
+ cmd: 'tools';
11
+ } | {
12
+ cmd: 'expand';
13
+ ord?: number;
14
+ } | {
15
+ cmd: 'resume';
16
+ id?: string;
17
+ } | {
18
+ cmd: 'clear';
19
+ } | {
20
+ cmd: 'exit';
21
+ };
22
+ export declare function parseCommand(line: string): ParsedCommand | null;
23
+ /** Commands whose name starts with what has been typed after the slash. */
24
+ export declare function filterCommands(input: string): TermCommand[];
25
+ //# sourceMappingURL=commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,aAAa,EAAE,WAAW,EAOtC,CAAC;AAEF,MAAM,MAAM,aAAa,GACrB;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,GACf;IAAE,GAAG,EAAE,OAAO,CAAA;CAAE,GAChB;IAAE,GAAG,EAAE,QAAQ,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,GAAG,EAAE,QAAQ,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,GAAG,EAAE,OAAO,CAAA;CAAE,GAChB;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAQpB,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAkB/D;AAED,2EAA2E;AAC3E,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,EAAE,CAK3D"}
@@ -0,0 +1,10 @@
1
+ import {
2
+ TERM_COMMANDS,
3
+ filterCommands,
4
+ parseCommand
5
+ } from "./chunk-R6AXTD55.js";
6
+ export {
7
+ TERM_COMMANDS,
8
+ filterCommands,
9
+ parseCommand
10
+ };
@@ -0,0 +1,25 @@
1
+ /** Preview lines kept from a tool result. Failure gets more, because the output
2
+ * you actually need is the output of the thing that broke. */
3
+ export declare const PREVIEW_LINES = 6;
4
+ export declare const PREVIEW_LINES_ERROR = 12;
5
+ /** A tool call in one line: the argument that says WHAT it is acting on. A path
6
+ * or a command is the difference between "it did something" and "it read my ssh
7
+ * config". */
8
+ export declare function describeToolCall(_name: string, args: unknown): string;
9
+ /** The lines of a tool result to commit, plus a marker when more was dropped. */
10
+ export declare function capPreview(result: string, isError: boolean): string[];
11
+ export interface ToolFact {
12
+ name: string;
13
+ description: string;
14
+ means?: string;
15
+ mutates?: boolean;
16
+ }
17
+ /**
18
+ * What the agent can do, in its own words.
19
+ *
20
+ * `list_tools` exists for the MODEL to introspect; this is for the person
21
+ * carrying the risk, who otherwise has no way to find out that the thing in
22
+ * their project directory can run arbitrary commands.
23
+ */
24
+ export declare function formatTools(tools: ToolFact[]): string;
25
+ //# sourceMappingURL=describe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"describe.d.ts","sourceRoot":"","sources":["../src/describe.ts"],"names":[],"mappings":"AAGA;8DAC8D;AAC9D,eAAO,MAAM,aAAa,IAAI,CAAC;AAC/B,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAItC;;cAEc;AACd,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,CAQrE;AAED,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,EAAE,CASrE;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,CASrD"}
@@ -0,0 +1,14 @@
1
+ import {
2
+ PREVIEW_LINES,
3
+ PREVIEW_LINES_ERROR,
4
+ capPreview,
5
+ describeToolCall,
6
+ formatTools
7
+ } from "./chunk-TCVDVYMF.js";
8
+ export {
9
+ PREVIEW_LINES,
10
+ PREVIEW_LINES_ERROR,
11
+ capPreview,
12
+ describeToolCall,
13
+ formatTools
14
+ };
@@ -0,0 +1,30 @@
1
+ import React from 'react';
2
+ import type { TuiState } from '../state';
3
+ export interface AppProps {
4
+ state: TuiState;
5
+ model: string;
6
+ cwd: string;
7
+ /** A launch fact (`--version` reports it), not steady-state metadata -- kept
8
+ * on the props type for callers, but no longer rendered anywhere in the face
9
+ * itself. */
10
+ version: string;
11
+ toolCount: number;
12
+ approveAll: boolean;
13
+ value: string;
14
+ onChange: (v: string) => void;
15
+ onSubmit: (v: string) => void;
16
+ onAnswer: (v: string) => void;
17
+ /** Whether the text field accepts keystrokes. False while the PERMISSION
18
+ * modal is open -- that one is y/n/esc only, so its answer is consumed ONCE
19
+ * by Root's key handler and never also lands as a stray character in the box.
20
+ * A QUESTION modal keeps focus on purpose: its answer can be typed as free
21
+ * text, and a bare digit against an empty field is intercepted as a pick in
22
+ * Root's `handleChange` (see ink/index.tsx). */
23
+ focus: boolean;
24
+ /** The palette's highlighted row, owned by Root so it survives across
25
+ * renders and can be moved with the arrow keys. */
26
+ paletteSelected: number;
27
+ }
28
+ /** The whole face: a <Static> region the terminal owns, and a live tail. */
29
+ export declare function App(props: AppProps): React.ReactElement;
30
+ //# sourceMappingURL=App.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/ink/App.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAInD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAyBzC,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,QAAQ,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ;;iBAEa;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B;;;;;oDAKgD;IAChD,KAAK,EAAE,OAAO,CAAC;IACf;uDACmD;IACnD,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,4EAA4E;AAC5E,wBAAgB,GAAG,CAAC,KAAK,EAAE,QAAQ,GAAG,KAAK,CAAC,YAAY,CAmFvD"}
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import type { Modal } from '../state';
3
+ export declare function ModalView({ modal }: {
4
+ modal: Modal;
5
+ }): React.ReactElement;
6
+ //# sourceMappingURL=Modal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Modal.d.ts","sourceRoot":"","sources":["../../src/ink/Modal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAGtC,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,KAAK,CAAA;CAAE,GAAG,KAAK,CAAC,YAAY,CAgCzE"}
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import type { TermCommand } from '../commands';
3
+ export declare function PaletteView({ items, selected }: {
4
+ items: TermCommand[];
5
+ selected: number;
6
+ }): React.ReactElement;
7
+ //# sourceMappingURL=Palette.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Palette.d.ts","sourceRoot":"","sources":["../../src/ink/Palette.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;IAAE,KAAK,EAAE,WAAW,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,KAAK,CAAC,YAAY,CAc/G"}
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ import { TermSession, type TermSessionDeps } from '../session';
3
+ export interface TuiDeps extends TermSessionDeps {
4
+ version: string;
5
+ /** Reopen a conversation before the first prompt. */
6
+ resume?: {
7
+ id?: string;
8
+ };
9
+ }
10
+ /** Exported for `interaction.test.tsx` only: driving real keystrokes through
11
+ * ink-testing-library's `stdin` requires rendering this directly, since
12
+ * `runTui` wires it to the real `render()` call and process streams. */
13
+ export declare function Root({ session, deps }: {
14
+ session: TermSession;
15
+ deps: TuiDeps;
16
+ }): React.ReactElement;
17
+ export declare function runTui(deps: TuiDeps): Promise<number>;
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ink/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAsD,MAAM,OAAO,CAAC;AAK3E,OAAO,EAAE,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAK/D,MAAM,WAAW,OAAQ,SAAQ,eAAe;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,MAAM,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1B;AAED;;wEAEwE;AACxE,wBAAgB,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;IAAE,OAAO,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG,KAAK,CAAC,YAAY,CAuHnG;AAED,wBAAsB,MAAM,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAkC3D"}