@sigrun/tui 0.1.1 → 0.2.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 (108) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/package.json +2 -2
  3. package/dist/actions.d.ts +0 -119
  4. package/dist/actions.js +0 -12
  5. package/dist/api.d.ts +0 -152
  6. package/dist/api.js +0 -189
  7. package/dist/blocks/braille.d.ts +0 -41
  8. package/dist/blocks/braille.js +0 -131
  9. package/dist/blocks/chart.d.ts +0 -20
  10. package/dist/blocks/chart.js +0 -397
  11. package/dist/blocks/collection/calendar.d.ts +0 -28
  12. package/dist/blocks/collection/calendar.js +0 -232
  13. package/dist/blocks/collection/card.d.ts +0 -36
  14. package/dist/blocks/collection/card.js +0 -128
  15. package/dist/blocks/collection/collection.d.ts +0 -9
  16. package/dist/blocks/collection/collection.js +0 -26
  17. package/dist/blocks/collection/grid.d.ts +0 -18
  18. package/dist/blocks/collection/grid.js +0 -72
  19. package/dist/blocks/collection/lanes.d.ts +0 -32
  20. package/dist/blocks/collection/lanes.js +0 -320
  21. package/dist/blocks/collection/list.d.ts +0 -30
  22. package/dist/blocks/collection/list.js +0 -273
  23. package/dist/blocks/collection/move.d.ts +0 -67
  24. package/dist/blocks/collection/move.js +0 -96
  25. package/dist/blocks/collection/shared.d.ts +0 -87
  26. package/dist/blocks/collection/shared.js +0 -177
  27. package/dist/blocks/collection/table.d.ts +0 -26
  28. package/dist/blocks/collection/table.js +0 -221
  29. package/dist/blocks/content.d.ts +0 -48
  30. package/dist/blocks/content.js +0 -253
  31. package/dist/blocks/context.d.ts +0 -96
  32. package/dist/blocks/context.js +0 -65
  33. package/dist/blocks/diff.d.ts +0 -21
  34. package/dist/blocks/diff.js +0 -25
  35. package/dist/blocks/ext-transport.d.ts +0 -70
  36. package/dist/blocks/ext-transport.js +0 -165
  37. package/dist/blocks/form/choice.d.ts +0 -54
  38. package/dist/blocks/form/choice.js +0 -175
  39. package/dist/blocks/form/fields.d.ts +0 -56
  40. package/dist/blocks/form/fields.js +0 -136
  41. package/dist/blocks/form/file.d.ts +0 -61
  42. package/dist/blocks/form/file.js +0 -121
  43. package/dist/blocks/form/form.d.ts +0 -53
  44. package/dist/blocks/form/form.js +0 -703
  45. package/dist/blocks/form/list.d.ts +0 -37
  46. package/dist/blocks/form/list.js +0 -70
  47. package/dist/blocks/form/values.d.ts +0 -20
  48. package/dist/blocks/form/values.js +0 -104
  49. package/dist/blocks/icons.d.ts +0 -14
  50. package/dist/blocks/icons.js +0 -74
  51. package/dist/blocks/image.d.ts +0 -39
  52. package/dist/blocks/image.js +0 -82
  53. package/dist/blocks/layout.d.ts +0 -31
  54. package/dist/blocks/layout.js +0 -155
  55. package/dist/blocks/log.d.ts +0 -24
  56. package/dist/blocks/log.js +0 -111
  57. package/dist/blocks/meter.d.ts +0 -16
  58. package/dist/blocks/meter.js +0 -50
  59. package/dist/blocks/page.d.ts +0 -54
  60. package/dist/blocks/page.js +0 -355
  61. package/dist/blocks/render.d.ts +0 -31
  62. package/dist/blocks/render.js +0 -145
  63. package/dist/blocks/surface-view.d.ts +0 -33
  64. package/dist/blocks/surface-view.js +0 -86
  65. package/dist/blocks/surface.d.ts +0 -75
  66. package/dist/blocks/surface.js +0 -468
  67. package/dist/blocks/tones.d.ts +0 -23
  68. package/dist/blocks/tones.js +0 -63
  69. package/dist/blocks/treeview.d.ts +0 -22
  70. package/dist/blocks/treeview.js +0 -121
  71. package/dist/blocks/width.d.ts +0 -32
  72. package/dist/blocks/width.js +0 -70
  73. package/dist/clipboard.d.ts +0 -20
  74. package/dist/clipboard.js +0 -19
  75. package/dist/editor-launch.d.ts +0 -34
  76. package/dist/editor-launch.js +0 -70
  77. package/dist/keymaps/emacs.d.ts +0 -18
  78. package/dist/keymaps/emacs.js +0 -172
  79. package/dist/keymaps/standard.d.ts +0 -17
  80. package/dist/keymaps/standard.js +0 -175
  81. package/dist/keymaps/types.d.ts +0 -43
  82. package/dist/keymaps/types.js +0 -28
  83. package/dist/keymaps/vim.d.ts +0 -48
  84. package/dist/keymaps/vim.js +0 -291
  85. package/dist/launch.d.ts +0 -149
  86. package/dist/launch.js +0 -446
  87. package/dist/sse.d.ts +0 -109
  88. package/dist/sse.js +0 -401
  89. package/dist/theme.d.ts +0 -51
  90. package/dist/theme.js +0 -119
  91. package/dist/ui/ambient.d.ts +0 -81
  92. package/dist/ui/ambient.js +0 -301
  93. package/dist/ui/app.d.ts +0 -245
  94. package/dist/ui/app.js +0 -1325
  95. package/dist/ui/composer.d.ts +0 -66
  96. package/dist/ui/composer.js +0 -125
  97. package/dist/ui/conversation-pane.d.ts +0 -123
  98. package/dist/ui/conversation-pane.js +0 -463
  99. package/dist/ui/help.d.ts +0 -15
  100. package/dist/ui/help.js +0 -80
  101. package/dist/ui/interactions.d.ts +0 -90
  102. package/dist/ui/interactions.js +0 -330
  103. package/dist/ui/picker.d.ts +0 -26
  104. package/dist/ui/picker.js +0 -130
  105. package/dist/ui/sidebar.d.ts +0 -99
  106. package/dist/ui/sidebar.js +0 -269
  107. package/dist/ui/status-bar.d.ts +0 -77
  108. package/dist/ui/status-bar.js +0 -146
@@ -1,121 +0,0 @@
1
- /**
2
- * The secret and file fields (UI-blocks U2 Task 5, spec §5.6).
3
- *
4
- * `secret` is write-only: it NEVER renders a value, only the bound
5
- * status — `set (stored)` / `set (env)` / `not set` — and a masked
6
- * editor (`•` per typed character; ASCII `*` with ctx.unicode false).
7
- *
8
- * `file` prompts for a path, checks `accept` (MIME patterns) and
9
- * `maxBytes`, reads the file's bytes, dispatches `onUpload` (a
10
- * `submit` action, turn false) with the file descriptor plus the base64
11
- * bytes, and hands the bytes to the surface's upload seam
12
- * (`uploadBytes`) when the host provides one (§7.2). A failed check
13
- * shows its error under the field and dispatches nothing.
14
- */
15
- import { readFileSync, statSync } from "node:fs";
16
- import { bindRaw } from "../context.js";
17
- import { truncate } from "../width.js";
18
- /** The secret status text (spec §5.6's exact strings). */
19
- export function secretStatusText(status) {
20
- if (status === "stored")
21
- return "set (stored)";
22
- if (status === "env")
23
- return "set (env)";
24
- return "not set";
25
- }
26
- /** The status line of a secret field: the bound status (the field's
27
- * name resolved against the form's bind, as U1's SecretField does). */
28
- export function secretStatusLine(field, formBind, ctx) {
29
- const pointer = `${formBind === "" ? "" : formBind}/${field.name}`.replace(/^\/+/, "/");
30
- const status = bindRaw({ $: pointer }, ctx);
31
- return secretStatusText(status);
32
- }
33
- /** The masked editor text: one dot per typed character. */
34
- export function maskText(textValue, unicode) {
35
- return (unicode ? "•" : "*").repeat(textValue.length);
36
- }
37
- /** Whether a file matches the accept patterns (comma-separated:
38
- * `image/*`, `image/png`, `.png`) — U1's `acceptsMime` rule, extended
39
- * with an extension fallback when the MIME guess is empty. */
40
- export function acceptsMime(accept, file) {
41
- if (accept === undefined || accept.trim() === "")
42
- return true;
43
- return accept.split(",").some((raw) => {
44
- const pattern = raw.trim();
45
- if (pattern === "")
46
- return false;
47
- if (pattern.startsWith("."))
48
- return file.name.endsWith(pattern);
49
- if (pattern.endsWith("/*")) {
50
- return file.type !== "" && file.type.startsWith(pattern.slice(0, -1));
51
- }
52
- return file.type === pattern;
53
- });
54
- }
55
- /** A small extension → MIME map (the TUI has no file picker; the type
56
- * is guessed from the name, empty when unknown). */
57
- const EXT_MIME = {
58
- ".png": "image/png",
59
- ".jpg": "image/jpeg",
60
- ".jpeg": "image/jpeg",
61
- ".gif": "image/gif",
62
- ".webp": "image/webp",
63
- ".svg": "image/svg+xml",
64
- ".txt": "text/plain",
65
- ".md": "text/markdown",
66
- ".json": "application/json",
67
- ".pdf": "application/pdf",
68
- };
69
- /** The MIME guess from a file name ("" when unknown). */
70
- export function mimeOf(name) {
71
- const dot = name.lastIndexOf(".");
72
- if (dot < 0)
73
- return "";
74
- return EXT_MIME[name.slice(dot).toLowerCase()] ?? "";
75
- }
76
- /**
77
- * Check `accept`/`maxBytes`, read the file and build the descriptor +
78
- * payload. A failure answers `{ok: false, error}` and nothing else
79
- * happens (no dispatch).
80
- */
81
- export function pickFile(field, path, read = (p) => new Uint8Array(readFileSync(p)), sizeOf = (p) => statSync(p).size) {
82
- const name = path.split("/").pop() ?? path;
83
- let size;
84
- let bytes;
85
- try {
86
- size = sizeOf(path);
87
- bytes = read(path);
88
- }
89
- catch {
90
- return { ok: false, error: `${path}: cannot read the file` };
91
- }
92
- const type = mimeOf(name);
93
- if (!acceptsMime(field.accept, { type, name })) {
94
- return { ok: false, error: `${name}: not an accepted type` };
95
- }
96
- if (field.maxBytes !== undefined && size > field.maxBytes) {
97
- return { ok: false, error: `${name} is larger than ${field.maxBytes} bytes` };
98
- }
99
- return {
100
- ok: true,
101
- descriptor: { name, size, type },
102
- bytes,
103
- payloadFile: {
104
- name,
105
- size,
106
- type,
107
- bytesBase64: Buffer.from(bytes).toString("base64"),
108
- },
109
- };
110
- }
111
- /** The per-field secret/file editor state (the path/masked buffer). */
112
- export class FileFieldState {
113
- error;
114
- uploaded = [];
115
- }
116
- /** The status line a file field shows after an upload. */
117
- export function fileStatusLine(state, width) {
118
- if (state.uploaded.length === 0)
119
- return undefined;
120
- return truncate(`uploaded: ${state.uploaded.join(", ")}`, width);
121
- }
@@ -1,53 +0,0 @@
1
- /**
2
- * The `form` block (UI-blocks U2 Task 5, spec §5.6/§6.2/§9.1 — the TUI
3
- * port of U1's `Form.tsx`): modes (submit / live / inline), client
4
- * validation before dispatch, the live-mode 300 ms debounce with the
5
- * `/view/` view-only branch, and the interaction stepper — several
6
- * sections each holding a `choice` in an interaction placement present
7
- * one question at a time with a review step, submitting ONCE with every
8
- * field's value.
9
- *
10
- * TUI editing model (the app owns keymaps; the form owns text editing):
11
- * Up/Down move between fields (the stepper moves BETWEEN sections);
12
- * the focused field edits inline — characters insert, Backspace
13
- * deletes, Enter submits (text/number/date/secret), toggles (toggle)
14
- * or activates an option (choice); Tab moves to the next field.
15
- * `syntax: "code"` longtext opens the host's $EDITOR seam with `e`.
16
- * Editing is per-mode: `submit` edits locally until Enter on the button
17
- * row; `live` dispatches every change after 300 ms (a `/view/`-bound
18
- * live form writes through ctx.setView and never dispatches); `inline`
19
- * renders one row (field plus the submit label) and clears on success.
20
- *
21
- * The focused field survives a data update (Review Focus 4): values
22
- * and focus live in the component, not the render; a re-render after a
23
- * server data change keeps both.
24
- */
25
- import type { Component } from "@earendil-works/pi-tui";
26
- import type { FormBlock, JsonObject, SectionBlock } from "@sigrun/shared/blocks";
27
- import { type BlockCtx } from "../context.js";
28
- /** The live-mode debounce (spec §5.6: "every change is applied after
29
- * 300 ms"). */
30
- export declare const LIVE_DEBOUNCE_MS = 300;
31
- /** The stepper: does this form qualify (several sections each holding
32
- * a choice, interaction placement)? (§9.1) */
33
- export declare function stepperSections(block: FormBlock, interaction: boolean): readonly SectionBlock[] | null;
34
- /** The form component. */
35
- export declare class FormComponent implements Component {
36
- #private;
37
- constructor(block: FormBlock, ctx: BlockCtx, opts?: {
38
- interaction?: boolean;
39
- });
40
- /** Render (the form re-renders against the current ctx data — the
41
- * host re-creates or re-renders on SurfaceState changes). */
42
- render(width: number): string[];
43
- /** Input handling (the host routes keys while the form has focus). */
44
- handleInput(data: string): void;
45
- invalidate(): void;
46
- /** Cancel any pending live debounce (the host's dispose seam). */
47
- dispose(): void;
48
- /** Test/host introspection: the current values and focus. */
49
- get values(): JsonObject;
50
- get focusIndex(): number;
51
- get step(): number;
52
- get submittedOnce(): boolean;
53
- }