@sigrun/tui 0.1.1 → 0.2.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.
Files changed (108) hide show
  1. package/CHANGELOG.md +11 -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
package/CHANGELOG.md CHANGED
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.2.1] - 2026-10-28
11
+ ### Fixed
12
+ - No user-facing TUI changes; versioned with the core family for the
13
+ listener, interaction, notification, and webui draft-restore fixes.
14
+
15
+ ## [0.2.0] - 2026-10-27
16
+ ### Added
17
+ - Block rendering extended for the U5/U6/U7 workstreams: chat-block
18
+ transcripts, interaction and ambient surfaces rendered from block trees,
19
+ settings forms on the live surface revision, and the block transports.
20
+
10
21
  ## [0.1.1] - 2026-10-24
11
22
  ### Added
12
23
  - Extension surfaces and live surface updates.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sigrun/tui",
3
- "version": "0.1.1",
3
+ "version": "0.2.1",
4
4
  "description": "sigrun terminal client (pi-tui based) over the \u00a75 API \u2014 spawned by the sigrun CLI, or standalone against a server URL",
5
5
  "type": "module",
6
6
  "bin": {
@@ -20,7 +20,7 @@
20
20
  },
21
21
  "dependencies": {
22
22
  "@earendil-works/pi-tui": "^1.3.0",
23
- "@sigrun/shared": "0.1.2"
23
+ "@sigrun/shared": "0.2.1"
24
24
  },
25
25
  "devDependencies": {
26
26
  "typescript": "^7.0.2",
package/dist/actions.d.ts DELETED
@@ -1,119 +0,0 @@
1
- /**
2
- * The TUI action layer (Task C3, UI refresh): a channel-neutral union of
3
- * everything the keymaps, pickers, mouse regions, and slash commands can
4
- * ask the shell to do. {@link TuiApp} implements {@link ActionHost} and
5
- * owns the focus state the focus/move/open actions drive.
6
- *
7
- * Focus targets: `composer` (the pi-tui Editor), `list` (the sidebar's
8
- * conversation tree), `transcript` (the pane's focusable turns). The
9
- * keymap decides WHICH action a key means per focus; the app decides
10
- * what the action DOES per focus.
11
- */
12
- /** The three focusable regions. `surface` (Task 4, UI-blocks U2) is a
13
- * block surface pane (lanes/calendar/collection) — the blocks.* keys
14
- * route ONLY while it has focus. While a surface is focused the
15
- * transcript/list nav keys (y/f/e//?) are inert (the keymaps pass
16
- * them); Task 6's surface host decides any surface-side meaning for
17
- * them. */
18
- export type Focus = "composer" | "list" | "transcript" | "surface";
19
- /** Every dispatchable intent. */
20
- export type Action = {
21
- readonly type: "focus";
22
- readonly target: Focus;
23
- } | {
24
- readonly type: "focus-cycle";
25
- readonly direction: 1 | -1;
26
- } | {
27
- readonly type: "move";
28
- readonly delta: number;
29
- } | {
30
- readonly type: "page";
31
- readonly direction: 1 | -1;
32
- readonly half: boolean;
33
- } | {
34
- readonly type: "edge";
35
- readonly to: "top" | "bottom";
36
- } | {
37
- readonly type: "prompt-jump";
38
- readonly delta: 1 | -1;
39
- } | {
40
- readonly type: "toggle-fold";
41
- } | {
42
- readonly type: "open";
43
- } | {
44
- readonly type: "copy";
45
- } | {
46
- readonly type: "fork-here";
47
- } | {
48
- readonly type: "edit-here";
49
- } | {
50
- readonly type: "edit-in-vim";
51
- } | {
52
- readonly type: "picker";
53
- readonly kind: "conversation" | "model" | "command";
54
- } | {
55
- readonly type: "new-conversation";
56
- } | {
57
- readonly type: "cycle-thinking";
58
- } | {
59
- readonly type: "search";
60
- readonly direction: "forward" | "backward";
61
- } | {
62
- readonly type: "search-next";
63
- readonly reverse: boolean;
64
- } | {
65
- readonly type: "answer-interaction";
66
- } | {
67
- readonly type: "cancel-run";
68
- } | {
69
- readonly type: "redraw";
70
- } | {
71
- readonly type: "quit";
72
- } | {
73
- readonly type: "help";
74
- } | {
75
- readonly type: "command-line";
76
- } | {
77
- readonly type: "run-command";
78
- readonly line: string;
79
- }
80
- /** Pick up the item under the cursor (m / M-m). */
81
- | {
82
- readonly type: "blocks.pickUp";
83
- }
84
- /** Drop the picked-up item at its placement (Enter). */
85
- | {
86
- readonly type: "blocks.drop";
87
- }
88
- /** Cancel the pick-up (Esc). */
89
- | {
90
- readonly type: "blocks.cancelMove";
91
- }
92
- /** Toggle the selection of the item under the cursor (Space). */
93
- | {
94
- readonly type: "blocks.select";
95
- }
96
- /** Open the action menu (`.` — bulk actions, "Move to…"). */
97
- | {
98
- readonly type: "blocks.actionMenu";
99
- }
100
- /** Toggle the checkable field of the item under the cursor (x). */
101
- | {
102
- readonly type: "blocks.check";
103
- }
104
- /** Previous calendar range ([). */
105
- | {
106
- readonly type: "blocks.rangePrev";
107
- }
108
- /** Next calendar range (]). */
109
- | {
110
- readonly type: "blocks.rangeNext";
111
- }
112
- /** Return the calendar range to today (t). */
113
- | {
114
- readonly type: "blocks.today";
115
- };
116
- /** The dispatch surface {@link TuiApp} implements. */
117
- export interface ActionHost {
118
- dispatch(action: Action): Promise<void>;
119
- }
package/dist/actions.js DELETED
@@ -1,12 +0,0 @@
1
- /**
2
- * The TUI action layer (Task C3, UI refresh): a channel-neutral union of
3
- * everything the keymaps, pickers, mouse regions, and slash commands can
4
- * ask the shell to do. {@link TuiApp} implements {@link ActionHost} and
5
- * owns the focus state the focus/move/open actions drive.
6
- *
7
- * Focus targets: `composer` (the pi-tui Editor), `list` (the sidebar's
8
- * conversation tree), `transcript` (the pane's focusable turns). The
9
- * keymap decides WHICH action a key means per focus; the app decides
10
- * what the action DOES per focus.
11
- */
12
- export {};
package/dist/api.d.ts DELETED
@@ -1,152 +0,0 @@
1
- /**
2
- * The TUI's typed §5 HTTP client (Task 4).
3
- *
4
- * Wire shapes are the channel contract — imported from the
5
- * `@sigrun/shared` package (`views`, plus `SessionMeta`/`SlashCommand`
6
- * siblings), the single source of truth shared with the server and the
7
- * webui (build-and-webui Task 1: the tui is a pure client of the wire,
8
- * never a relative importer of server source).
9
- *
10
- * Identity seam (Task 2): the configured `user` rides EVERY request as the
11
- * `X-Sigrun-User` header; absent/empty user omits it entirely — the
12
- * server's naive mode. The bearer token (Task 7) rides every request as
13
- * `authorization: Bearer <token>` when configured.
14
- *
15
- * Fail-loud: a non-2xx rejects with a {@link SigrunApiError} carrying the
16
- * status and the server's parsed error body (`{error: ...}`), never a
17
- * silent `undefined` the UI could misrender as empty state.
18
- */
19
- import type { CommandRunResponse, CommandsResponse } from "@sigrun/shared/commands";
20
- import type { JobsResponse, JobRunResponse } from "@sigrun/shared/views";
21
- import type { JobRevisionWire, JobRunWire } from "@sigrun/shared/jobs";
22
- import type { SessionMeta, SessionMetaPatch } from "@sigrun/shared/session-meta";
23
- import type { AbortResponse, AmbientList, CompactResponse, ConfigureResponse, ConversationCreateResponse, ConversationForkResponse, ConversationList, ConversationViewWire, InteractionAnswered, InteractionList, ModelsResponse, SettingsResponse, SubmissionResponse } from "@sigrun/shared/views";
24
- export type { AbortResponse, AmbientList, AmbientWire, CompactResponse, ConfigureResponse, ConversationCreateResponse, ConversationForkResponse, ConversationList, ConversationSummary, ConversationViewWire, InteractionAnswered, InteractionList, InteractionWire, ModelEntry, ModelsResponse, SettingsResponse, SubmissionResponse, } from "@sigrun/shared/views";
25
- export type { CommandRunResponse, CommandsResponse, SlashCommand } from "@sigrun/shared/commands";
26
- export type { JobSpec, JobSchedule, JobAction, JobWire, JobRunWire, JobRevisionWire, } from "@sigrun/shared/jobs";
27
- export type { JobsResponse, JobRunResponse } from "@sigrun/shared/views";
28
- export type { ExtensionsResponse, ExtensionInfo, ExtensionSurfaceInfo } from "@sigrun/shared/views";
29
- export type { SessionMeta, SessionMetaPatch } from "@sigrun/shared/session-meta";
30
- /** One answer to a pending interaction (the ONE generic route's body). */
31
- export interface InteractionAnswerInput {
32
- readonly ids?: readonly string[];
33
- readonly values?: Readonly<Record<string, string | number | boolean>>;
34
- readonly text?: string;
35
- }
36
- /** `GET /v1/jobs/:id/runs`: the job's runs, newest first. */
37
- export interface JobRunsResponse {
38
- readonly runs: readonly JobRunWire[];
39
- }
40
- /** `GET /v1/jobs/:id/revisions`: the job's revisions, newest first. */
41
- export interface JobRevisionsResponse {
42
- readonly revisions: readonly JobRevisionWire[];
43
- }
44
- /** The `whenBusy` admission modes the server accepts (spec §7 item 3). */
45
- export type WhenBusyMode = "steer" | "followUp" | "reject";
46
- /** A non-2xx response: status + the server's parsed error body. */
47
- export declare class SigrunApiError extends Error {
48
- readonly status: number;
49
- readonly body: unknown;
50
- constructor(method: string, path: string, status: number, body: unknown);
51
- }
52
- /** The fetch surface the client needs (the real thing or a test stub). */
53
- export type FetchLike = (input: string, init?: {
54
- readonly method?: string;
55
- readonly headers?: Record<string, string>;
56
- readonly body?: string;
57
- }) => Promise<{
58
- readonly ok: boolean;
59
- readonly status: number;
60
- json(): Promise<unknown>;
61
- text(): Promise<string>;
62
- }>;
63
- export interface SigrunClientOptions {
64
- /**
65
- * The server's origin (e.g. `http://127.0.0.1:PORT`) — the TUI is a
66
- * remote client, so unlike the webui there is no same-origin default.
67
- */
68
- readonly baseUrl: string;
69
- /**
70
- * The `X-Sigrun-User` identity (Task 2). Absent/empty/whitespace → the
71
- * header is omitted entirely (the server's naive mode).
72
- */
73
- readonly user?: string;
74
- /**
75
- * A bearer token (Task 7): rides EVERY request as
76
- * `authorization: Bearer <token>`. Absent/empty/whitespace → omitted.
77
- * The launcher threads `SIGRUN_TOKEN` here — the env beats tui.json.
78
- */
79
- readonly token?: string;
80
- /** Injected for tests; defaults to the ambient `fetch`. */
81
- readonly fetch?: FetchLike;
82
- }
83
- /** The typed §5 client. See {@link SigrunClientOptions} for the seams. */
84
- import type { ExtensionsResponse } from "@sigrun/shared/views";
85
- export declare class SigrunClient {
86
- #private;
87
- constructor(options: SigrunClientOptions);
88
- /** `GET /v1/conversations` — all durable conversations (Task 3). */
89
- listConversations(): Promise<ConversationList>;
90
- /** `GET /v1/conversations/:id` — the full wire view (one frame). */
91
- getConversation(id: number): Promise<ConversationViewWire>;
92
- /** `POST /v1/conversations` — the new id plus its first view frame. */
93
- createConversation(): Promise<ConversationCreateResponse>;
94
- /** `POST /v1/conversations/:id/fork` (absent `at` = the newest entry). */
95
- forkConversation(id: number, at?: number): Promise<ConversationForkResponse>;
96
- /**
97
- * `POST /v1/conversations/:id/submissions` — plain text input; 202 at
98
- * ADMISSION (§7.1) with the record as it stands. The TUI is
99
- * fire-and-forget: the reply arrives as view revisions on the stream,
100
- * not from this response.
101
- */
102
- submit(id: number, text: string, whenBusy?: WhenBusyMode): Promise<SubmissionResponse>;
103
- /** `POST /v1/conversations/:id/abort`. */
104
- abort(id: number): Promise<AbortResponse>;
105
- /**
106
- * `POST /v1/conversations/:id/compact` — admits a manual compaction;
107
- * the summary entry arrives later as a view revision on the stream.
108
- */
109
- compact(id: number, instructions?: string): Promise<CompactResponse>;
110
- /** `GET /v1/conversations/:id/meta`. */
111
- getMeta(id: number): Promise<SessionMeta>;
112
- /** `PATCH /v1/conversations/:id/meta` — merges; resolves to the new meta. */
113
- patchMeta(id: number, patch: SessionMetaPatch): Promise<SessionMeta>;
114
- /** `GET /v1/conversations/:id/interactions` — pending interactions. */
115
- listInteractions(id: number): Promise<InteractionList>;
116
- /** `POST .../interactions/:callId/answer` — the ONE generic answer route. */
117
- answerInteraction(id: number, callId: string, answer: InteractionAnswerInput): Promise<InteractionAnswered>;
118
- /** `GET /v1/conversations/:id/ambient`. */
119
- getAmbient(id: number): Promise<AmbientList>;
120
- /** `GET /v1/commands` — the slash-command catalog (a boot constant). */
121
- getCommands(): Promise<CommandsResponse>;
122
- /** `GET /v1/extensions` — the loaded-extension inventory (U3 Task 5:
123
- * the sidebar's Views group + panels read the declared surfaces). */
124
- listExtensions(): Promise<ExtensionsResponse>;
125
- /**
126
- * `POST /v1/conversations/:id/commands/:name` — invoke an extension
127
- * slash command (W5 Task 3): the server runs the winning declaration
128
- * and resolves with its optional `{notice}`.
129
- */
130
- runCommand(id: number, name: string, args?: string): Promise<CommandRunResponse>;
131
- /** `GET /v1/settings` — the effective settings (absent file = `{}`). */
132
- getSettings(): Promise<SettingsResponse>;
133
- /** `GET /v1/models` — the chat-model catalog (the model picker's items). */
134
- listModels(): Promise<ModelsResponse>;
135
- /**
136
- * `POST /v1/conversations/:id/configure` — change the model and/or
137
- * thinking level (T9c-i). At least one field is required (the server
138
- * rejects an empty change as `invalid_body`).
139
- */
140
- configure(id: number, body: {
141
- readonly model?: string;
142
- readonly thinking?: string;
143
- }): Promise<ConfigureResponse>;
144
- /** `GET /v1/jobs` — the caller-visible jobs (`/jobs`, W4 Task 5). */
145
- listJobs(): Promise<JobsResponse>;
146
- /** `POST /v1/jobs/:id/run` — fire a job now (write access). */
147
- runJob(id: string): Promise<JobRunResponse>;
148
- /** `GET /v1/jobs/:id/runs` — the job's runs, newest first. */
149
- listJobRuns(id: string, limit?: number): Promise<JobRunsResponse>;
150
- /** `GET /v1/jobs/:id/revisions` — the job's revisions, newest first. */
151
- listJobRevisions(id: string): Promise<JobRevisionsResponse>;
152
- }
package/dist/api.js DELETED
@@ -1,189 +0,0 @@
1
- /**
2
- * The TUI's typed §5 HTTP client (Task 4).
3
- *
4
- * Wire shapes are the channel contract — imported from the
5
- * `@sigrun/shared` package (`views`, plus `SessionMeta`/`SlashCommand`
6
- * siblings), the single source of truth shared with the server and the
7
- * webui (build-and-webui Task 1: the tui is a pure client of the wire,
8
- * never a relative importer of server source).
9
- *
10
- * Identity seam (Task 2): the configured `user` rides EVERY request as the
11
- * `X-Sigrun-User` header; absent/empty user omits it entirely — the
12
- * server's naive mode. The bearer token (Task 7) rides every request as
13
- * `authorization: Bearer <token>` when configured.
14
- *
15
- * Fail-loud: a non-2xx rejects with a {@link SigrunApiError} carrying the
16
- * status and the server's parsed error body (`{error: ...}`), never a
17
- * silent `undefined` the UI could misrender as empty state.
18
- */
19
- /** A non-2xx response: status + the server's parsed error body. */
20
- export class SigrunApiError extends Error {
21
- status;
22
- body;
23
- constructor(method, path, status, body) {
24
- super(`sigrun api: ${method} ${path} failed with status ${status}`);
25
- this.name = "SigrunApiError";
26
- this.status = status;
27
- this.body = body;
28
- }
29
- }
30
- export class SigrunClient {
31
- #baseUrl;
32
- #fetch;
33
- #headers;
34
- constructor(options) {
35
- // A trailing slash would double every route's leading one
36
- // (`--server http://host/` → `//v1/...`) — normalize once.
37
- this.#baseUrl = options.baseUrl.replace(/\/+$/, "");
38
- this.#fetch =
39
- options.fetch ??
40
- ((input, init) => globalThis.fetch(input, init));
41
- const user = options.user?.trim();
42
- const token = options.token?.trim();
43
- this.#headers = {
44
- accept: "application/json",
45
- ...(user === undefined || user === "" ? {} : { "x-sigrun-user": user }),
46
- ...(token === undefined || token === ""
47
- ? {}
48
- : { authorization: `Bearer ${token}` }),
49
- };
50
- }
51
- async #get(path) {
52
- const response = await this.#fetch(`${this.#baseUrl}${path}`, {
53
- method: "GET",
54
- headers: this.#headers,
55
- });
56
- if (!response.ok) {
57
- throw new SigrunApiError("GET", path, response.status, await response.json().catch(() => undefined));
58
- }
59
- return (await response.json());
60
- }
61
- async #send(method, path, body) {
62
- const response = await this.#fetch(`${this.#baseUrl}${path}`, {
63
- method,
64
- headers: { ...this.#headers, "content-type": "application/json" },
65
- body: JSON.stringify(body),
66
- });
67
- if (!response.ok) {
68
- throw new SigrunApiError(method, path, response.status, await response.json().catch(() => undefined));
69
- }
70
- return (await response.json());
71
- }
72
- /** `GET /v1/conversations` — all durable conversations (Task 3). */
73
- listConversations() {
74
- return this.#get("/v1/conversations");
75
- }
76
- /** `GET /v1/conversations/:id` — the full wire view (one frame). */
77
- getConversation(id) {
78
- return this.#get(`/v1/conversations/${id}`);
79
- }
80
- /** `POST /v1/conversations` — the new id plus its first view frame. */
81
- createConversation() {
82
- return this.#send("POST", "/v1/conversations", {});
83
- }
84
- /** `POST /v1/conversations/:id/fork` (absent `at` = the newest entry). */
85
- forkConversation(id, at) {
86
- return this.#send("POST", `/v1/conversations/${id}/fork`, {
87
- ...(at === undefined ? {} : { at }),
88
- });
89
- }
90
- /**
91
- * `POST /v1/conversations/:id/submissions` — plain text input; 202 at
92
- * ADMISSION (§7.1) with the record as it stands. The TUI is
93
- * fire-and-forget: the reply arrives as view revisions on the stream,
94
- * not from this response.
95
- */
96
- submit(id, text, whenBusy) {
97
- return this.#send("POST", `/v1/conversations/${id}/submissions`, {
98
- input: [{ type: "text", text }],
99
- ...(whenBusy === undefined ? {} : { whenBusy }),
100
- });
101
- }
102
- /** `POST /v1/conversations/:id/abort`. */
103
- abort(id) {
104
- return this.#send("POST", `/v1/conversations/${id}/abort`, {});
105
- }
106
- /**
107
- * `POST /v1/conversations/:id/compact` — admits a manual compaction;
108
- * the summary entry arrives later as a view revision on the stream.
109
- */
110
- compact(id, instructions) {
111
- return this.#send("POST", `/v1/conversations/${id}/compact`, {
112
- ...(instructions === undefined || instructions === ""
113
- ? {}
114
- : { instructions }),
115
- });
116
- }
117
- /** `GET /v1/conversations/:id/meta`. */
118
- getMeta(id) {
119
- return this.#get(`/v1/conversations/${id}/meta`);
120
- }
121
- /** `PATCH /v1/conversations/:id/meta` — merges; resolves to the new meta. */
122
- patchMeta(id, patch) {
123
- return this.#send("PATCH", `/v1/conversations/${id}/meta`, patch);
124
- }
125
- /** `GET /v1/conversations/:id/interactions` — pending interactions. */
126
- listInteractions(id) {
127
- return this.#get(`/v1/conversations/${id}/interactions`);
128
- }
129
- /** `POST .../interactions/:callId/answer` — the ONE generic answer route. */
130
- answerInteraction(id, callId, answer) {
131
- return this.#send("POST", `/v1/conversations/${id}/interactions/${encodeURIComponent(callId)}/answer`, answer);
132
- }
133
- /** `GET /v1/conversations/:id/ambient`. */
134
- getAmbient(id) {
135
- return this.#get(`/v1/conversations/${id}/ambient`);
136
- }
137
- /** `GET /v1/commands` — the slash-command catalog (a boot constant). */
138
- getCommands() {
139
- return this.#get("/v1/commands");
140
- }
141
- /** `GET /v1/extensions` — the loaded-extension inventory (U3 Task 5:
142
- * the sidebar's Views group + panels read the declared surfaces). */
143
- listExtensions() {
144
- return this.#get("/v1/extensions");
145
- }
146
- /**
147
- * `POST /v1/conversations/:id/commands/:name` — invoke an extension
148
- * slash command (W5 Task 3): the server runs the winning declaration
149
- * and resolves with its optional `{notice}`.
150
- */
151
- runCommand(id, name, args) {
152
- return this.#send("POST", `/v1/conversations/${id}/commands/${encodeURIComponent(name)}`, {
153
- args: args ?? "",
154
- });
155
- }
156
- /** `GET /v1/settings` — the effective settings (absent file = `{}`). */
157
- getSettings() {
158
- return this.#get("/v1/settings");
159
- }
160
- /** `GET /v1/models` — the chat-model catalog (the model picker's items). */
161
- listModels() {
162
- return this.#get("/v1/models");
163
- }
164
- /**
165
- * `POST /v1/conversations/:id/configure` — change the model and/or
166
- * thinking level (T9c-i). At least one field is required (the server
167
- * rejects an empty change as `invalid_body`).
168
- */
169
- configure(id, body) {
170
- return this.#send("POST", `/v1/conversations/${id}/configure`, body);
171
- }
172
- /** `GET /v1/jobs` — the caller-visible jobs (`/jobs`, W4 Task 5). */
173
- listJobs() {
174
- return this.#get("/v1/jobs");
175
- }
176
- /** `POST /v1/jobs/:id/run` — fire a job now (write access). */
177
- runJob(id) {
178
- return this.#send("POST", `/v1/jobs/${encodeURIComponent(id)}/run`, {});
179
- }
180
- /** `GET /v1/jobs/:id/runs` — the job's runs, newest first. */
181
- listJobRuns(id, limit) {
182
- return this.#get(`/v1/jobs/${encodeURIComponent(id)}/runs` +
183
- (limit === undefined ? "" : `?limit=${limit}`));
184
- }
185
- /** `GET /v1/jobs/:id/revisions` — the job's revisions, newest first. */
186
- listJobRevisions(id) {
187
- return this.#get(`/v1/jobs/${encodeURIComponent(id)}/revisions`);
188
- }
189
- }
@@ -1,41 +0,0 @@
1
- /**
2
- * The Braille dot canvas and the display ramps (UI-blocks spec §5.4):
3
- * the pieces `chart` and the narrow-fallback sparkline draw with.
4
- *
5
- * - {@link BrailleCanvas} is a `cells×rows` cell grid of 2×4 dot
6
- * subpixels (Unicode Braille Patterns, U+2800 base). Each cell also
7
- * records the index of the series that plotted into it LAST, which
8
- * is how multi-colour charts colour a shared cell.
9
- * - {@link sparkline} renders a value series onto the eighth-block
10
- * ramp `▁▂▃▄▅▆▇█` (or the ASCII ramp `_.,-+=*#` on a no-Unicode
11
- * terminal), downsampling with the shared `lttb` when the series is
12
- * longer than the cell budget.
13
- */
14
- /** A Braille dot canvas: `cells` columns × `rows` rows of 2×4 dots. */
15
- export declare class BrailleCanvas {
16
- #private;
17
- constructor(cells: number, rows: number);
18
- /** Plot one dot; out-of-range coordinates are ignored. */
19
- plot(x: number, y: number, series?: number): void;
20
- /** A straight dot-space line from (x0, y0) to (x1, y1): the steps
21
- * are the CHEBYSHEV distance (diagonal-adjacent dots step one
22
- * dot-space cell at a time). */
23
- line(x0: number, y0: number, x1: number, y1: number, series?: number): void;
24
- /** Fill the dot rectangle (x0..x1, y0..y1) inclusive. */
25
- fill(x0: number, y0: number, x1: number, y1: number, series?: number): void;
26
- /** The dot bits set in one cell. */
27
- cellBits(cellX: number, cellY: number): number;
28
- /** The series index that plotted into this cell last (−1: none). */
29
- cellOwner(cellX: number, cellY: number): number;
30
- /** Clear one cell row (a threshold rule paints over it). */
31
- blankRow(cellY: number): void;
32
- /** The canvas as one Braille string per cell row. */
33
- rows(): string[];
34
- }
35
- /**
36
- * A one-cell-per-sample sparkline of `values`, at most `maxCells`
37
- * cells (longer series downsample with `lttb`, keeping both ends).
38
- * `unicode: false` selects the ASCII ramp. Empty input renders empty;
39
- * a flat series renders mid-height cells.
40
- */
41
- export declare function sparkline(values: readonly number[], maxCells: number, unicode: boolean): string;