@alisio/alisio-code 0.1.0-alpha.9 → 0.1.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 (56) hide show
  1. package/README.md +95 -16
  2. package/dist/analysis.d.ts +27 -0
  3. package/dist/analysis.js +145 -0
  4. package/dist/banner.js +2 -1
  5. package/dist/builtin.d.ts +3 -1
  6. package/dist/builtin.js +0 -24
  7. package/dist/main.js +133 -6
  8. package/dist/serve.d.ts +15 -0
  9. package/dist/serve.js +99 -0
  10. package/dist/tui/agent-manager.d.ts +105 -0
  11. package/dist/tui/agent-manager.js +269 -0
  12. package/dist/tui/agents.d.ts +5 -0
  13. package/dist/tui/agents.js +5 -0
  14. package/dist/tui/app.d.ts +42 -1
  15. package/dist/tui/app.js +1895 -97
  16. package/dist/tui/artifact-preview.d.ts +52 -0
  17. package/dist/tui/artifact-preview.js +212 -0
  18. package/dist/tui/artifacts.d.ts +54 -0
  19. package/dist/tui/artifacts.js +207 -0
  20. package/dist/tui/btw.d.ts +57 -0
  21. package/dist/tui/btw.js +76 -0
  22. package/dist/tui/components.d.ts +174 -12
  23. package/dist/tui/components.js +962 -66
  24. package/dist/tui/connect-input.d.ts +2 -0
  25. package/dist/tui/connect-input.js +1 -1
  26. package/dist/tui/exit.d.ts +10 -0
  27. package/dist/tui/exit.js +15 -0
  28. package/dist/tui/git-branch.d.ts +48 -0
  29. package/dist/tui/git-branch.js +99 -0
  30. package/dist/tui/goal.d.ts +75 -0
  31. package/dist/tui/goal.js +171 -0
  32. package/dist/tui/modes.d.ts +71 -0
  33. package/dist/tui/modes.js +90 -0
  34. package/dist/tui/open-path.d.ts +38 -0
  35. package/dist/tui/open-path.js +80 -0
  36. package/dist/tui/plan-review.d.ts +48 -0
  37. package/dist/tui/plan-review.js +76 -0
  38. package/dist/tui/queue.d.ts +2 -0
  39. package/dist/tui/queue.js +5 -1
  40. package/dist/tui/scroll.d.ts +8 -0
  41. package/dist/tui/scroll.js +12 -0
  42. package/dist/tui/settings-menu.d.ts +40 -0
  43. package/dist/tui/settings-menu.js +132 -0
  44. package/dist/tui/settings.d.ts +194 -0
  45. package/dist/tui/settings.js +482 -0
  46. package/dist/tui/state.d.ts +343 -7
  47. package/dist/tui/state.js +823 -54
  48. package/dist/tui/tasks.d.ts +123 -0
  49. package/dist/tui/tasks.js +369 -0
  50. package/dist/tui/theme.d.ts +42 -1
  51. package/dist/tui/theme.js +516 -1
  52. package/dist/tui/viewer-state.d.ts +7 -0
  53. package/dist/tui/viewer-state.js +36 -0
  54. package/dist/version.d.ts +7 -5
  55. package/dist/version.js +44 -8
  56. package/package.json +7 -9
@@ -1,24 +1,57 @@
1
- import type { PanelNode } from "@alisio/sdk";
1
+ import type { PanelNode, TreeNode, UiBlock } from "@alisio/sdk";
2
2
  import { type Component, Container } from "@earendil-works/pi-tui";
3
3
  import { type PendingAttachment } from "./attachments.ts";
4
+ import { type BtwAction, type BtwState } from "./btw.ts";
5
+ import { type PlanReviewEffect, type PlanReviewOption } from "./plan-review.ts";
4
6
  import { type QuestionPanelState, type QuestionSpec } from "./questions.ts";
5
- import { type ContextBudget, type TranscriptItem, type ViewState } from "./state.ts";
7
+ import { type ContextBudget, type FoldableKind, type FoldCandidate, type GroupedTool, type IdentityInput, type TranscriptEntry, type TranscriptItem, type ViewState } from "./state.ts";
6
8
  export declare const SPINNER: string[];
7
9
  /** Shared animation clock advanced by the app while work is running. */
8
10
  export declare const clock: {
9
11
  frame: number;
10
12
  now: number;
11
13
  };
14
+ /** Fold state the components receive: neither knows keys nor defaults (components stay dumb). */
15
+ export interface FoldInfo {
16
+ expanded: boolean;
17
+ kind: FoldableKind;
18
+ }
19
+ /** `Command exited with code 0.` (green) / `Command exited with code N.` (red) when known. */
20
+ export declare const exitCodeLine: (code: number | undefined, indent?: string) => string | undefined;
21
+ /**
22
+ * Tree rendering with branch glyphs: `├─`/`└─`/`│` when the terminal supports Unicode, ASCII
23
+ * `|-`/`` `- ``/`|` otherwise.
24
+ */
25
+ export declare function renderTreeLines(nodes: TreeNode[], unicode: boolean): string[];
26
+ export declare function setArtifactPathResolver(resolve: ((id: string) => string | undefined) | undefined): void;
27
+ /** The two-line announcement of an `artifact` block (kind, name, size and local path). */
28
+ export declare function renderArtifactBlock(block: Extract<UiBlock, {
29
+ kind: "artifact";
30
+ }>, width: number, unicode: boolean, path?: string): string[];
31
+ /**
32
+ * Renders a `{type:"ui"}` block to styled lines for the given inner width. Blocks come from
33
+ * persisted transcripts too, so anything that does not validate (a kind added by a newer Alisio,
34
+ * or a malformed plugin block) falls back to labeled JSON instead of throwing.
35
+ */
36
+ export declare function renderUiBlock(block: UiBlock, width: number, unicode: boolean): string[];
12
37
  export type PermissionState = "on" | "ask" | "off";
13
38
  export interface HeaderInfo {
14
39
  version: string;
15
40
  host: string;
16
41
  apiMode: string;
17
42
  provider?: string;
43
+ /** Model display name (catalog `name`), falling back to the session model id. */
44
+ modelName?: string;
45
+ /** Effective reasoning effort of the active model, when it advertises supported levels. */
46
+ effort?: string;
18
47
  cwd: string;
19
48
  session: string;
49
+ /** Git branch (or short SHA on a detached HEAD) of the session workspace; undefined when unavailable. */
50
+ branch?: string;
20
51
  write: PermissionState;
21
52
  process: PermissionState;
53
+ /** Permission mode shown as `mode:<name>` next to the effect states. */
54
+ mode?: string;
22
55
  mcp: boolean;
23
56
  readOnly: boolean;
24
57
  }
@@ -34,7 +67,8 @@ export declare class Footer implements Component {
34
67
  private budget;
35
68
  private hint;
36
69
  private statuses;
37
- constructor(view: () => ViewState, budget: () => ContextBudget | undefined, hint: () => string | undefined, statuses?: () => string[]);
70
+ private identity?;
71
+ constructor(view: () => ViewState, budget: () => ContextBudget | undefined, hint: () => string | undefined, statuses?: () => string[], identity?: (() => IdentityInput | undefined) | undefined);
38
72
  invalidate(): void;
39
73
  render(width: number): string[];
40
74
  }
@@ -46,13 +80,17 @@ export declare class UserBlock implements Component {
46
80
  }
47
81
  export declare class AssistantBlock implements Component {
48
82
  private markdown;
83
+ /** Bumped by TranscriptSync when this row's content changes; render caches on it. */
84
+ version: number;
85
+ fold?: FoldInfo;
49
86
  private item;
87
+ private cache?;
50
88
  constructor(item: Extract<TranscriptItem, {
51
89
  kind: "assistant";
52
90
  }>);
53
91
  update(item: Extract<TranscriptItem, {
54
92
  kind: "assistant";
55
- }>): void;
93
+ }>, fold?: FoldInfo | undefined): void;
56
94
  invalidate(): void;
57
95
  render(width: number): string[];
58
96
  }
@@ -60,9 +98,34 @@ export declare class ToolBlock implements Component {
60
98
  item: Extract<TranscriptItem, {
61
99
  kind: "tool";
62
100
  }>;
101
+ /** Bumped by TranscriptSync when this row's content changes; render caches on it. */
102
+ version: number;
103
+ fold?: FoldInfo;
104
+ private markdown?;
105
+ private cache?;
63
106
  constructor(item: Extract<TranscriptItem, {
64
107
  kind: "tool";
65
108
  }>);
109
+ update(item: Extract<TranscriptItem, {
110
+ kind: "tool";
111
+ }>, fold?: FoldInfo | undefined): void;
112
+ invalidate(): void;
113
+ render(width: number): string[];
114
+ }
115
+ /**
116
+ * One collapsible row for a GROUPED batch of finished tool calls (e.g. `✓ Read File — 3 reads`).
117
+ * Collapsed it shows the aggregate header; expanded, each call with its status, duration,
118
+ * summary and capped preview/rich body. All members are terminal, so lines are cached per
119
+ * version/width/fold just like the other terminal rows.
120
+ */
121
+ export declare class ToolGroupBlock implements Component {
122
+ group: GroupedTool;
123
+ /** Bumped by TranscriptSync when this row's content changes; render caches on it. */
124
+ version: number;
125
+ fold?: FoldInfo;
126
+ private cache?;
127
+ constructor(group: GroupedTool);
128
+ update(group: GroupedTool, fold?: FoldInfo | undefined): void;
66
129
  invalidate(): void;
67
130
  render(width: number): string[];
68
131
  }
@@ -79,22 +142,66 @@ export declare class InfoBlock implements Component {
79
142
  invalidate(): void;
80
143
  render(width: number): string[];
81
144
  }
82
- export declare function componentFor(item: TranscriptItem): Component;
83
- /** Startup screen rendered by core for the current width (cached until the width changes). */
84
- export declare class BannerBlock implements Component {
85
- private renderLines;
86
- private cache?;
87
- constructor(renderLines: (width: number) => string[]);
145
+ /**
146
+ * Minimum usable inner width (cells) the transcript keeps no matter how narrow the terminal is or
147
+ * how large the configured inset grows. The effective inset is clamped so this floor is honored,
148
+ * which also keeps the inner width positive.
149
+ */
150
+ export declare const MIN_CONTENT_WIDTH = 20;
151
+ /**
152
+ * Inset actually applied on each side: the configured value capped so the inner column stays at
153
+ * least `MIN_CONTENT_WIDTH` wide. On terminals narrower than that floor the inset degrades to 0
154
+ * rather than overflowing (the inner width then simply equals the terminal width).
155
+ */
156
+ export declare function effectiveContentInset(width: number, inset: number): number;
157
+ /** Inner width handed to transcript children after the effective inset is applied. Always >= 1. */
158
+ export declare function contentInnerWidth(width: number, inset: number): number;
159
+ /**
160
+ * Applies the transcript's horizontal inset in ONE place: it hands children a reduced width and
161
+ * prefixes every produced line with the inset, so all transcript chrome (text, copy hint, tool
162
+ * sub-lines, reasoning lines, group headers) shares the same visual column. The reduced width is a
163
+ * deterministic function of the terminal width, so per-row caches keyed by width stay effective.
164
+ */
165
+ export declare class ContentInset implements Component {
166
+ private readonly inner;
167
+ private readonly inset;
168
+ constructor(inner: Component, inset: () => number);
88
169
  invalidate(): void;
89
170
  render(width: number): string[];
90
171
  }
91
- /** Keeps a container of transcript components in step with view-model items. */
172
+ export declare function componentFor(entry: TranscriptEntry): Component;
173
+ /**
174
+ * Keeps a container of transcript components in step with view-model items. Rows are keyed
175
+ * (stable per fold candidate: tool ids, group ids, append-only item indices) and reused across
176
+ * syncs; batch groups replace their members' singleton components with one row once all of them
177
+ * finish. Content versions bump only when a row's entry actually changed, so clock frames
178
+ * between events reuse each component's cached lines instead of re-rendering. `setFoldResolver`
179
+ * supplies the effective expanded state; the same resolution feeds `entryAt`, so keybindings
180
+ * and mouse clicks agree with the renderer.
181
+ */
92
182
  export declare class TranscriptSync {
93
183
  readonly container: Container;
94
- private rendered;
184
+ private rows;
185
+ private order;
186
+ private foldOf;
187
+ setFoldResolver(resolver: (candidate: FoldCandidate) => boolean): void;
95
188
  sync(items: TranscriptItem[]): void;
189
+ /**
190
+ * Fold candidate at a transcript content row, when the click landed on the row's header
191
+ * (assistant entries start with a blank spacer line, so their first two rows count). Used by
192
+ * click-to-toggle; keyboard toggling uses `foldCandidates` instead and needs no heights.
193
+ */
194
+ entryAt(contentY: number, width: number): FoldCandidate | undefined;
96
195
  reset(): void;
97
196
  }
197
+ /** Startup screen rendered by core for the current width (cached until the width changes). */
198
+ export declare class BannerBlock implements Component {
199
+ private renderLines;
200
+ private cache?;
201
+ constructor(renderLines: (width: number) => string[]);
202
+ invalidate(): void;
203
+ render(width: number): string[];
204
+ }
98
205
  /** Renders one of several components (main conversation or a read-only child view). */
99
206
  export declare class Switch implements Component {
100
207
  private pick;
@@ -157,3 +264,58 @@ export declare class QuestionPanel implements Component {
157
264
  handleInput(data: string): void;
158
265
  render(width: number): string[];
159
266
  }
267
+ /**
268
+ * The plan review panel (`exit_plan`): the three decisions under the plan the transcript already
269
+ * shows. "Add context" turns the panel into a one-line text field (Enter sends, Esc goes back);
270
+ * Esc while choosing is "Skip for now". The logic lives in `plan-review.ts`.
271
+ */
272
+ export declare class PlanReviewPanel implements Component {
273
+ private header;
274
+ private onSubmit;
275
+ private placeholder;
276
+ private state;
277
+ constructor(options: PlanReviewOption[], header: {
278
+ title: string;
279
+ revision: number;
280
+ artifactId?: string;
281
+ question: string;
282
+ }, onSubmit: (effect: PlanReviewEffect) => void, placeholder?: string);
283
+ invalidate(): void;
284
+ private dispatch;
285
+ handleInput(data: string): void;
286
+ render(width: number): string[];
287
+ }
288
+ /**
289
+ * The `/btw` side-question panel (picker slot, never the transcript): a pending question with a
290
+ * spinner, then the answer rendered as Markdown like assistant text, scrollable, with ←/→ through
291
+ * the session's earlier side answers. `onClose` runs on Esc (the app cancels a pending question).
292
+ */
293
+ /**
294
+ * A scrollable Markdown panel in the picker slot (`/changelog`): Up/Down and PgUp/PgDn scroll,
295
+ * Home/End jump, Esc or q closes. Pure rendering: the text and the height come from the caller.
296
+ */
297
+ export declare class MarkdownPanel implements Component {
298
+ private readonly title;
299
+ private readonly markdown;
300
+ private readonly onClose;
301
+ private readonly height;
302
+ private scroll;
303
+ private cache?;
304
+ constructor(title: string, markdown: string, onClose: () => void, height: () => number);
305
+ invalidate(): void;
306
+ handleInput(data: string): void;
307
+ render(width: number): string[];
308
+ }
309
+ export declare class BtwPanel implements Component {
310
+ private state;
311
+ private readonly onClose;
312
+ private readonly height;
313
+ private markdown?;
314
+ constructor(state: BtwState, onClose: () => void, height: () => number);
315
+ get pending(): boolean;
316
+ dispatch(action: BtwAction): void;
317
+ invalidate(): void;
318
+ handleInput(data: string): void;
319
+ private answerLines;
320
+ render(width: number): string[];
321
+ }