@aragon-agent/cli 0.6.8 → 0.6.9
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.
- package/CHANGELOG.md +27 -0
- package/README.md +38 -37
- package/dist/agent/controller.d.ts +1 -1
- package/dist/agent/reducer.d.ts +7 -113
- package/dist/agent/reducer.js +0 -62
- package/dist/cli.js +48 -149
- package/dist/commands/perf.d.ts +32 -2
- package/dist/commands/perf.js +32 -2
- package/dist/commands/registry.d.ts +2 -2
- package/dist/config/env.js +0 -130
- package/dist/config/load.d.ts +0 -2
- package/dist/config/load.js +2 -31
- package/dist/config/schema.d.ts +1 -14
- package/dist/config/schema.js +0 -1
- package/dist/config/store.js +2 -0
- package/dist/logging/install.d.ts +2 -2
- package/dist/logging/install.js +2 -2
- package/dist/todo/follow-through.d.ts +0 -4
- package/dist/todo/follow-through.js +0 -4
- package/dist/todo/limits.d.ts +0 -10
- package/dist/todo/limits.js +0 -10
- package/dist/todo/prompt.d.ts +0 -15
- package/dist/ui/ActivityLine.d.ts +26 -34
- package/dist/ui/ActivityLine.js +30 -19
- package/dist/ui/App.d.ts +1 -41
- package/dist/ui/App.js +66 -128
- package/dist/ui/BottomStatusRow.d.ts +1 -3
- package/dist/ui/BottomStatusRow.js +4 -8
- package/dist/ui/Composer.d.ts +28 -1
- package/dist/ui/Composer.js +43 -17
- package/dist/ui/Header.d.ts +2 -16
- package/dist/ui/Header.js +3 -18
- package/dist/ui/Logo.d.ts +1 -17
- package/dist/ui/Logo.js +0 -16
- package/dist/ui/ModeChip.d.ts +7 -18
- package/dist/ui/ModeChip.js +9 -0
- package/dist/ui/PromptInput.d.ts +2 -28
- package/dist/ui/PromptInput.js +4 -7
- package/dist/ui/StatusBar.d.ts +0 -11
- package/dist/ui/ToastStack.d.ts +2 -18
- package/dist/ui/ToastStack.js +4 -11
- package/dist/ui/Transcript.d.ts +5 -71
- package/dist/ui/Transcript.js +9 -199
- package/dist/ui/entries/AssistantEntry.d.ts +0 -23
- package/dist/ui/entries/AssistantEntry.js +3 -4
- package/dist/ui/entries/DiffView.d.ts +1 -7
- package/dist/ui/entries/DiffView.js +2 -2
- package/dist/ui/entries/ToolCard.d.ts +0 -6
- package/dist/ui/entries/ToolCard.js +4 -13
- package/dist/ui/frame-differ.d.ts +13 -0
- package/dist/ui/frame-differ.js +36 -6
- package/dist/ui/ink-runtime.d.ts +1 -0
- package/dist/ui/ink-runtime.js +21 -0
- package/dist/ui/layout/AppShell.d.ts +1 -10
- package/dist/ui/layout/AppShell.js +2 -5
- package/dist/ui/layout/OverlayFrame.d.ts +1 -25
- package/dist/ui/layout/OverlayFrame.js +0 -24
- package/dist/ui/layout/ScrollViewport.d.ts +3 -0
- package/dist/ui/layout/ScrollViewport.js +17 -5
- package/dist/ui/layout/frame.d.ts +0 -22
- package/dist/ui/layout/frame.js +0 -36
- package/dist/ui/layout/todo-layout.d.ts +1 -3
- package/dist/ui/layout/todo-layout.js +7 -8
- package/dist/ui/layout/viewport-geometry.d.ts +1 -1
- package/dist/ui/layout/viewport-geometry.js +1 -1
- package/dist/ui/live-clamp.d.ts +1 -29
- package/dist/ui/live-clamp.js +1 -29
- package/dist/ui/overlays/HelpOverlay.js +1 -0
- package/dist/ui/run-status-row.d.ts +61 -0
- package/dist/ui/run-status-row.js +70 -0
- package/dist/ui/transcript-text.d.ts +0 -8
- package/dist/ui/transcript-text.js +0 -8
- package/dist/ui/use-startup-notices.d.ts +1 -57
- package/dist/ui/use-startup-notices.js +3 -54
- package/dist/ui/use-wheel-routing.d.ts +1 -1
- package/package.json +2 -2
- package/dist/ui/TodoStrip.d.ts +0 -36
- package/dist/ui/TodoStrip.js +0 -32
|
@@ -1,28 +1,4 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
/**
|
|
3
|
-
* OverlayFrame (spec §4.4) — the shared shell for all four overlays.
|
|
4
|
-
*
|
|
5
|
-
* TWO CONTENT MODES, and the distinction is load-bearing:
|
|
6
|
-
*
|
|
7
|
-
* - mode A (`rows`): the caller hands over an array of elements that are each
|
|
8
|
-
* exactly one row and `wrap="truncate"`. The frame slices them and OWNS the
|
|
9
|
-
* scroll keys. Used by Help and Settings.
|
|
10
|
-
*
|
|
11
|
-
* - mode B (`children`): the content manages itself. The frame draws the title,
|
|
12
|
-
* the border and the footer, and touches NOTHING else — no slicing, no
|
|
13
|
-
* arrow-key handling, no position indicator.
|
|
14
|
-
*
|
|
15
|
-
* Mode B exists because of `ink-select-input`: it already windows itself via
|
|
16
|
-
* `limit` and registers its own `useInput` with `isFocused` defaulting to true.
|
|
17
|
-
* Ink dispatches a key to EVERY mounted input handler, so a frame that also
|
|
18
|
-
* claimed the arrow keys would move the model picker's selection twice per press
|
|
19
|
-
* — breaking a feature that already works. Slicing it by element would be worse
|
|
20
|
-
* still, since it is a single component rather than a list of rows.
|
|
21
|
-
*
|
|
22
|
-
* `maxRows` may be `Infinity` (the inline render path, which has no fixed frame
|
|
23
|
-
* and therefore no height to fit): the frame then renders everything and shows
|
|
24
|
-
* no position indicator.
|
|
25
|
-
*/
|
|
26
2
|
import { useEffect } from 'react';
|
|
27
3
|
import { Box, Text } from 'ink';
|
|
28
4
|
import { pickGlyphs } from '../glyphs.js';
|
|
@@ -27,6 +27,9 @@ export interface ScrollViewportProps {
|
|
|
27
27
|
scrollbar?: ScrollbarBridge;
|
|
28
28
|
composerRef?: React.RefObject<DOMElement>;
|
|
29
29
|
onComposerVisibilityChange?: (visible: boolean) => void;
|
|
30
|
+
/** The run status row above the input box (tui-scrollbar-edge-and-run-row). */
|
|
31
|
+
activityRef?: React.RefObject<DOMElement>;
|
|
32
|
+
onActivityVisibilityChange?: (visible: boolean) => void;
|
|
30
33
|
theme: Theme;
|
|
31
34
|
caps: TermCapabilities;
|
|
32
35
|
children: React.ReactNode;
|
|
@@ -8,17 +8,23 @@ import { reduceFollow, shouldArmResume } from './follow-state.js';
|
|
|
8
8
|
import { thumbRange } from './scroll-indicator.js';
|
|
9
9
|
import { ScrollIndicator } from './ScrollIndicator.js';
|
|
10
10
|
import { buildDocumentLayout } from './document-layout.js';
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Whether `element` lies fully inside `clip`. A missing element (not mounted) or
|
|
13
|
+
* clip reports `true`, so a caller that consumes the answer must first know the
|
|
14
|
+
* element is actually mounted. Rows are one line tall, so "partially visible"
|
|
15
|
+
* cannot occur for the run status row.
|
|
16
|
+
*/
|
|
17
|
+
function elementVisible(element, clip) {
|
|
18
|
+
if (!element || !clip)
|
|
13
19
|
return true;
|
|
14
20
|
let top = 0;
|
|
15
|
-
let current =
|
|
21
|
+
let current = element;
|
|
16
22
|
while (current && current !== clip) {
|
|
17
23
|
top += current.yogaNode?.getComputedTop() ?? 0;
|
|
18
24
|
current = current.parentNode;
|
|
19
25
|
}
|
|
20
26
|
return current === clip && top >= 0 &&
|
|
21
|
-
top + measureElement(
|
|
27
|
+
top + measureElement(element).height <= measureElement(clip).height;
|
|
22
28
|
}
|
|
23
29
|
/** One offset for messages, padding and editor; hidden trees keep their local state. */
|
|
24
30
|
export function ScrollViewport(props) {
|
|
@@ -45,6 +51,7 @@ export function ScrollViewport(props) {
|
|
|
45
51
|
const lastPin = useRef(props.pinToBottomNonce);
|
|
46
52
|
const lastReset = useRef(props.resetKey);
|
|
47
53
|
const lastVisible = useRef();
|
|
54
|
+
const lastActivityVisible = useRef();
|
|
48
55
|
const previousActive = useRef(active);
|
|
49
56
|
const geometryRevision = useRef(0);
|
|
50
57
|
const geometryBounds = useRef('');
|
|
@@ -186,11 +193,16 @@ export function ScrollViewport(props) {
|
|
|
186
193
|
thumb: thumbRange(viewport, content, next, true), revision: geometryRevision.current };
|
|
187
194
|
scrollbar.onGeometry?.();
|
|
188
195
|
}
|
|
189
|
-
const visible =
|
|
196
|
+
const visible = elementVisible(props.composerRef?.current ?? null, clipRef.current);
|
|
190
197
|
if (lastVisible.current !== visible) {
|
|
191
198
|
lastVisible.current = visible;
|
|
192
199
|
props.onComposerVisibilityChange?.(visible);
|
|
193
200
|
}
|
|
201
|
+
const activityVisible = elementVisible(props.activityRef?.current ?? null, clipRef.current);
|
|
202
|
+
if (lastActivityVisible.current !== activityVisible) {
|
|
203
|
+
lastActivityVisible.current = activityVisible;
|
|
204
|
+
props.onActivityVisibilityChange?.(activityVisible);
|
|
205
|
+
}
|
|
194
206
|
});
|
|
195
207
|
const shiftUp = Math.max(0, metrics.content - metrics.viewport - offset);
|
|
196
208
|
useEffect(() => { props.onScrolledLinesChange?.(offset); }, [offset, props.onScrolledLinesChange]);
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
* Two pure functions with zero React dependency so the load-bearing invariant
|
|
5
5
|
* I-1 (`frameHeight(r) < r`) can be pinned by a unit test rather than by hope.
|
|
6
6
|
*/
|
|
7
|
-
export type RenderMode = 'fullscreen' | 'inline';
|
|
8
7
|
/** Below this many rows a full-screen frame has no usable viewport left. */
|
|
9
8
|
export declare const MIN_FULLSCREEN_ROWS = 12;
|
|
10
9
|
/** Below this many columns the chrome (composer + status bar) cannot line-wrap sanely. */
|
|
@@ -35,24 +34,3 @@ export declare const FALLBACK_COLS = 80;
|
|
|
35
34
|
* terminal is strictly better than a per-frame full-screen repaint.
|
|
36
35
|
*/
|
|
37
36
|
export declare function frameHeight(rows: number | undefined): number;
|
|
38
|
-
interface StdoutLike {
|
|
39
|
-
isTTY?: boolean;
|
|
40
|
-
rows?: number;
|
|
41
|
-
columns?: number;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Decide the render mode once, at startup (never re-decided at run time —
|
|
45
|
-
* entering/leaving the alt-screen mid-session is a state machine we do not want).
|
|
46
|
-
*
|
|
47
|
-
* Order is semantics, not style:
|
|
48
|
-
* 1. an explicit opt-out always wins (users can always get v0.2.0 back);
|
|
49
|
-
* 2. `isTTY` is the one gate `--fullscreen` cannot override — writing ANSI into
|
|
50
|
-
* a pipe or a redirected file is a contract violation, whereas a heuristic
|
|
51
|
-
* misfire only costs polish;
|
|
52
|
-
* 3. the explicit force comes next so it can beat the heuristics below;
|
|
53
|
-
* 4. heuristics (TERM/CI/size), all overridable by `--fullscreen`.
|
|
54
|
-
*/
|
|
55
|
-
export declare function decideRenderMode(flags: {
|
|
56
|
-
fullscreen?: boolean;
|
|
57
|
-
}, env: Record<string, string | undefined>, stdout: StdoutLike | undefined): RenderMode;
|
|
58
|
-
export {};
|
package/dist/ui/layout/frame.js
CHANGED
|
@@ -37,39 +37,3 @@ export function frameHeight(rows) {
|
|
|
37
37
|
const r = rows && rows > 0 ? rows : FALLBACK_ROWS;
|
|
38
38
|
return Math.max(0, r - 1);
|
|
39
39
|
}
|
|
40
|
-
/** `CI=` / `CI=0` / `CI=false` are not CI; anything else non-empty is. */
|
|
41
|
-
function isTruthyEnv(value) {
|
|
42
|
-
if (value === undefined)
|
|
43
|
-
return false;
|
|
44
|
-
const v = value.trim().toLowerCase();
|
|
45
|
-
return v.length > 0 && v !== '0' && v !== 'false';
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Decide the render mode once, at startup (never re-decided at run time —
|
|
49
|
-
* entering/leaving the alt-screen mid-session is a state machine we do not want).
|
|
50
|
-
*
|
|
51
|
-
* Order is semantics, not style:
|
|
52
|
-
* 1. an explicit opt-out always wins (users can always get v0.2.0 back);
|
|
53
|
-
* 2. `isTTY` is the one gate `--fullscreen` cannot override — writing ANSI into
|
|
54
|
-
* a pipe or a redirected file is a contract violation, whereas a heuristic
|
|
55
|
-
* misfire only costs polish;
|
|
56
|
-
* 3. the explicit force comes next so it can beat the heuristics below;
|
|
57
|
-
* 4. heuristics (TERM/CI/size), all overridable by `--fullscreen`.
|
|
58
|
-
*/
|
|
59
|
-
export function decideRenderMode(flags, env, stdout) {
|
|
60
|
-
if (flags.fullscreen === false)
|
|
61
|
-
return 'inline';
|
|
62
|
-
if (!stdout?.isTTY)
|
|
63
|
-
return 'inline';
|
|
64
|
-
if (flags.fullscreen === true)
|
|
65
|
-
return 'fullscreen';
|
|
66
|
-
if (env.TERM === 'dumb')
|
|
67
|
-
return 'inline';
|
|
68
|
-
if (isTruthyEnv(env.CI))
|
|
69
|
-
return 'inline';
|
|
70
|
-
if ((stdout.rows ?? 0) < MIN_FULLSCREEN_ROWS)
|
|
71
|
-
return 'inline';
|
|
72
|
-
if ((stdout.columns ?? 0) < MIN_FULLSCREEN_COLS)
|
|
73
|
-
return 'inline';
|
|
74
|
-
return 'fullscreen';
|
|
75
|
-
}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import type { RenderMode } from './frame.js';
|
|
2
1
|
export interface TodoRailLayoutInput {
|
|
3
|
-
mode: RenderMode;
|
|
4
2
|
cols: number;
|
|
5
3
|
panelEnabled: boolean;
|
|
6
4
|
overlayOpen: boolean;
|
|
@@ -12,7 +10,7 @@ export interface TodoRailLayoutInput {
|
|
|
12
10
|
}
|
|
13
11
|
export interface TodoRailLayout {
|
|
14
12
|
visible: boolean;
|
|
15
|
-
reason: 'visible' | '
|
|
13
|
+
reason: 'visible' | 'disabled' | 'overlay' | 'empty' | 'narrow' | 'short';
|
|
16
14
|
width: number;
|
|
17
15
|
rows: number;
|
|
18
16
|
contentCols: number;
|
|
@@ -11,15 +11,14 @@ export function buildTodoRailLayout(input) {
|
|
|
11
11
|
const popupMaxHeight = Math.max(0, budget - teamRows - TODO_LIMITS.panelMinRows
|
|
12
12
|
- nonNegativeInt(input.composerBaseRows ?? 0));
|
|
13
13
|
const popupRows = popupMaxHeight < 3 ? 0 : Math.min(nonNegativeInt(input.popupRows), popupMaxHeight);
|
|
14
|
-
const rows =
|
|
14
|
+
const rows = budget;
|
|
15
15
|
const width = todoRailWidth(cols);
|
|
16
|
-
const reason = input.
|
|
17
|
-
:
|
|
18
|
-
: input.
|
|
19
|
-
:
|
|
20
|
-
:
|
|
21
|
-
:
|
|
22
|
-
: 'visible';
|
|
16
|
+
const reason = !input.panelEnabled ? 'disabled'
|
|
17
|
+
: input.overlayOpen ? 'overlay'
|
|
18
|
+
: nonNegativeInt(input.itemCount) === 0 ? 'empty'
|
|
19
|
+
: width === 0 ? 'narrow'
|
|
20
|
+
: rows < TODO_LIMITS.panelMinRows ? 'short'
|
|
21
|
+
: 'visible';
|
|
23
22
|
const visible = reason === 'visible';
|
|
24
23
|
return { visible, reason, width, rows, contentCols: cols - (visible ? width : 0), popupMaxHeight };
|
|
25
24
|
}
|
|
@@ -21,7 +21,7 @@ export interface ViewportGeometry {
|
|
|
21
21
|
}
|
|
22
22
|
/**
|
|
23
23
|
* The default is the UNMEASURED geometry, and consumers must treat it as such:
|
|
24
|
-
* a `TranscriptList` rendered outside a `ScrollViewport` (
|
|
24
|
+
* a `TranscriptList` rendered outside a `ScrollViewport` (including
|
|
25
25
|
* test that mounts it bare) sees `viewportRows: 0`, which `selectWindow` reads
|
|
26
26
|
* as "first frame" and answers by pinning the live tail.
|
|
27
27
|
*/
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
import { createContext, useContext } from 'react';
|
|
14
14
|
/**
|
|
15
15
|
* The default is the UNMEASURED geometry, and consumers must treat it as such:
|
|
16
|
-
* a `TranscriptList` rendered outside a `ScrollViewport` (
|
|
16
|
+
* a `TranscriptList` rendered outside a `ScrollViewport` (including
|
|
17
17
|
* test that mounts it bare) sees `viewportRows: 0`, which `selectWindow` reads
|
|
18
18
|
* as "first frame" and answers by pinning the live tail.
|
|
19
19
|
*/
|
package/dist/ui/live-clamp.d.ts
CHANGED
|
@@ -1,32 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Live-region clamp for INLINE render mode (tui-render-performance L5 / R6).
|
|
3
|
-
*
|
|
4
|
-
* Inline mode has no fixed frame, so nothing kept its live (non-`<Static>`)
|
|
5
|
-
* region shorter than the terminal. When one live entry grew taller than
|
|
6
|
-
* `stdout.rows`, Ink took the branch at `ink.js:118-123`:
|
|
7
|
-
*
|
|
8
|
-
* if (outputHeight >= this.options.stdout.rows) {
|
|
9
|
-
* stdout.write(clearTerminal + this.fullStaticOutput + output);
|
|
10
|
-
* }
|
|
11
|
-
*
|
|
12
|
-
* `fullStaticOutput` accumulates EVERY `<Static>` frame of the whole session and
|
|
13
|
-
* is never trimmed, so once that branch is taken it is taken on every subsequent
|
|
14
|
-
* frame — bypassing both the `output !== lastOutput` dedupe and `throttledLog` —
|
|
15
|
-
* and the terminal receives the entire session history thirty times a second.
|
|
16
|
-
* That is a genuine hard freeze, and it is reachable today by any inline user
|
|
17
|
-
* (`--no-fullscreen`, `TERM=dumb`, CI, a short or narrow terminal) whose model
|
|
18
|
-
* writes a long answer.
|
|
19
|
-
*
|
|
20
|
-
* I-L5-1 — keeping the live region strictly below `stdout.rows` makes that
|
|
21
|
-
* branch UNREACHABLE, which is the inline analogue of `frame.ts`'s
|
|
22
|
-
* `frameHeight(r) < r` and deserves the same standing. We cannot bound Ink's
|
|
23
|
-
* `fullStaticOutput` growth (it is private and append-only); preventing the
|
|
24
|
-
* branch that WRITES it is the entire mitigation, and nothing about the memory
|
|
25
|
-
* it holds is fixed by this module.
|
|
26
|
-
*
|
|
27
|
-
* Nothing is lost, only deferred: when the entry settles it moves into
|
|
28
|
-
* `<Static>` and is printed in full.
|
|
29
|
-
*/
|
|
1
|
+
/** Keep the newest thinking lines visible while an assistant entry streams. */
|
|
30
2
|
export interface LiveClamp {
|
|
31
3
|
text: string;
|
|
32
4
|
/** Rows dropped off the FRONT. `0` means the text was returned untouched. */
|
package/dist/ui/live-clamp.js
CHANGED
|
@@ -1,32 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Live-region clamp for INLINE render mode (tui-render-performance L5 / R6).
|
|
3
|
-
*
|
|
4
|
-
* Inline mode has no fixed frame, so nothing kept its live (non-`<Static>`)
|
|
5
|
-
* region shorter than the terminal. When one live entry grew taller than
|
|
6
|
-
* `stdout.rows`, Ink took the branch at `ink.js:118-123`:
|
|
7
|
-
*
|
|
8
|
-
* if (outputHeight >= this.options.stdout.rows) {
|
|
9
|
-
* stdout.write(clearTerminal + this.fullStaticOutput + output);
|
|
10
|
-
* }
|
|
11
|
-
*
|
|
12
|
-
* `fullStaticOutput` accumulates EVERY `<Static>` frame of the whole session and
|
|
13
|
-
* is never trimmed, so once that branch is taken it is taken on every subsequent
|
|
14
|
-
* frame — bypassing both the `output !== lastOutput` dedupe and `throttledLog` —
|
|
15
|
-
* and the terminal receives the entire session history thirty times a second.
|
|
16
|
-
* That is a genuine hard freeze, and it is reachable today by any inline user
|
|
17
|
-
* (`--no-fullscreen`, `TERM=dumb`, CI, a short or narrow terminal) whose model
|
|
18
|
-
* writes a long answer.
|
|
19
|
-
*
|
|
20
|
-
* I-L5-1 — keeping the live region strictly below `stdout.rows` makes that
|
|
21
|
-
* branch UNREACHABLE, which is the inline analogue of `frame.ts`'s
|
|
22
|
-
* `frameHeight(r) < r` and deserves the same standing. We cannot bound Ink's
|
|
23
|
-
* `fullStaticOutput` growth (it is private and append-only); preventing the
|
|
24
|
-
* branch that WRITES it is the entire mitigation, and nothing about the memory
|
|
25
|
-
* it holds is fixed by this module.
|
|
26
|
-
*
|
|
27
|
-
* Nothing is lost, only deferred: when the entry settles it moves into
|
|
28
|
-
* `<Static>` and is printed in full.
|
|
29
|
-
*/
|
|
1
|
+
/** Keep the newest thinking lines visible while an assistant entry streams. */
|
|
30
2
|
/**
|
|
31
3
|
* Keep the LAST `maxRows` rows of `text`; report how many were dropped.
|
|
32
4
|
*
|
|
@@ -27,6 +27,7 @@ function keyRows(times) {
|
|
|
27
27
|
// a key, so it has to be named somewhere they can look it up. The one-shot
|
|
28
28
|
// startup notice is the other place, and it scrolls away.
|
|
29
29
|
['Drag right edge', 'Scroll messages and input together; type to return'],
|
|
30
|
+
['Run status row', 'Spinner and steer / interrupt keys, above the input during a run'],
|
|
30
31
|
['Drag text (left button)', 'Select text on screen; releasing copies it'],
|
|
31
32
|
['Up / Down', 'Prompt history (empty input)'],
|
|
32
33
|
// Pasting is the one affordance here with no key of its own, so the only
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The run status row's width plan (tui-scrollbar-edge-and-run-row §3.3.3).
|
|
3
|
+
*
|
|
4
|
+
* While a run is in flight, ONE row above the input box carries the spinner, the
|
|
5
|
+
* phrase and the `steer / interrupt / exit` hint clauses, and `planRunRow` decides
|
|
6
|
+
* what survives when the line is too narrow. It is a pure function with no React
|
|
7
|
+
* and no I/O so the whole ladder can be tested as arithmetic.
|
|
8
|
+
*
|
|
9
|
+
* THE ALLOCATION IS PER CLAUSE, NOT PER STRING, and that is the whole point.
|
|
10
|
+
* The idle hint row this one replaces owned the full line width and ended in
|
|
11
|
+
* `wrap="truncate"`; handing the label half the line and truncating the joined
|
|
12
|
+
* hint would cut `interrupt` to `inter...` at 38 columns - a regression of the
|
|
13
|
+
* "running hint is NEVER abbreviated" rule `Composer.hintText` documents. So:
|
|
14
|
+
*
|
|
15
|
+
* - clauses are dropped WHOLE, from the tail (`exit`, then `stop N`), and
|
|
16
|
+
* - `steer` and `interrupt` (REQUIRED_CLAUSES) are never dropped or cut mid-word
|
|
17
|
+
* while the row is enabled, and
|
|
18
|
+
* - the only thing allowed to end in an ellipsis is the label.
|
|
19
|
+
*/
|
|
20
|
+
/** Everything the label needs, kept in one shape so there is one place that names it. */
|
|
21
|
+
export interface RunActivity {
|
|
22
|
+
/** Epoch ms the current run began - the phrase sequence's seed. */
|
|
23
|
+
startedAt: number;
|
|
24
|
+
/** `Date.now() - startedAt`, already computed by App's 200 ms ticker. */
|
|
25
|
+
elapsedMs: number;
|
|
26
|
+
/** The RAW config flag, never the widened one (single-spinner D-5). */
|
|
27
|
+
reducedMotion: boolean;
|
|
28
|
+
/** The tool currently in flight, if any. */
|
|
29
|
+
runningTool?: string;
|
|
30
|
+
/** A context compaction is in flight; outranks the tool name and the phrase. */
|
|
31
|
+
compacting?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export interface RunRowPlanInput {
|
|
34
|
+
/** Width of the row's container (the composer's content columns). */
|
|
35
|
+
cols: number;
|
|
36
|
+
/** Spinner + space + label, in display columns (the label's natural width). */
|
|
37
|
+
labelCols: number;
|
|
38
|
+
/** Display width of each hint clause, most urgent first. */
|
|
39
|
+
hintClauseCols: readonly number[];
|
|
40
|
+
/** Display width of the separator between clauses (` · ` or ` - `). */
|
|
41
|
+
separatorCols: number;
|
|
42
|
+
/** Display width of the right-aligned mode chip; 0 = no chip. */
|
|
43
|
+
chipCols: number;
|
|
44
|
+
}
|
|
45
|
+
export interface RunRowPlan {
|
|
46
|
+
/** Columns the label may occupy; below its natural width it is ellipsized. */
|
|
47
|
+
labelCols: number;
|
|
48
|
+
/** How many leading clauses to show; 0 = none (defensive tier only). */
|
|
49
|
+
hintClauses: number;
|
|
50
|
+
/** Whether the chip fits after everything else. */
|
|
51
|
+
chip: boolean;
|
|
52
|
+
}
|
|
53
|
+
/** One leading space, matching the idle hint row's `' '` indent. */
|
|
54
|
+
export declare const RUN_ROW_LEAD = 1;
|
|
55
|
+
/** Narrowest the label may be squeezed before a clause is dropped instead. */
|
|
56
|
+
export declare const RUN_ROW_MIN_LABEL_COLS = 10;
|
|
57
|
+
/** `steer` and `interrupt`: always whole while the row is enabled. */
|
|
58
|
+
export declare const RUN_ROW_REQUIRED_CLAUSES = 2;
|
|
59
|
+
/** Space kept between the last clause and the chip. */
|
|
60
|
+
export declare const RUN_ROW_CHIP_GAP = 2;
|
|
61
|
+
export declare function planRunRow(input: RunRowPlanInput): RunRowPlan;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The run status row's width plan (tui-scrollbar-edge-and-run-row §3.3.3).
|
|
3
|
+
*
|
|
4
|
+
* While a run is in flight, ONE row above the input box carries the spinner, the
|
|
5
|
+
* phrase and the `steer / interrupt / exit` hint clauses, and `planRunRow` decides
|
|
6
|
+
* what survives when the line is too narrow. It is a pure function with no React
|
|
7
|
+
* and no I/O so the whole ladder can be tested as arithmetic.
|
|
8
|
+
*
|
|
9
|
+
* THE ALLOCATION IS PER CLAUSE, NOT PER STRING, and that is the whole point.
|
|
10
|
+
* The idle hint row this one replaces owned the full line width and ended in
|
|
11
|
+
* `wrap="truncate"`; handing the label half the line and truncating the joined
|
|
12
|
+
* hint would cut `interrupt` to `inter...` at 38 columns - a regression of the
|
|
13
|
+
* "running hint is NEVER abbreviated" rule `Composer.hintText` documents. So:
|
|
14
|
+
*
|
|
15
|
+
* - clauses are dropped WHOLE, from the tail (`exit`, then `stop N`), and
|
|
16
|
+
* - `steer` and `interrupt` (REQUIRED_CLAUSES) are never dropped or cut mid-word
|
|
17
|
+
* while the row is enabled, and
|
|
18
|
+
* - the only thing allowed to end in an ellipsis is the label.
|
|
19
|
+
*/
|
|
20
|
+
/** One leading space, matching the idle hint row's `' '` indent. */
|
|
21
|
+
export const RUN_ROW_LEAD = 1;
|
|
22
|
+
/** Narrowest the label may be squeezed before a clause is dropped instead. */
|
|
23
|
+
export const RUN_ROW_MIN_LABEL_COLS = 10;
|
|
24
|
+
/** `steer` and `interrupt`: always whole while the row is enabled. */
|
|
25
|
+
export const RUN_ROW_REQUIRED_CLAUSES = 2;
|
|
26
|
+
/** Space kept between the last clause and the chip. */
|
|
27
|
+
export const RUN_ROW_CHIP_GAP = 2;
|
|
28
|
+
/** Non-finite or negative widths collapse to 0 so no input can make the plan throw. */
|
|
29
|
+
function width(value) {
|
|
30
|
+
return Number.isFinite(value) && value > 0 ? Math.floor(value) : 0;
|
|
31
|
+
}
|
|
32
|
+
/** Width of the first `count` clauses joined by `separator`. */
|
|
33
|
+
function clausesWidth(clauses, count, separator) {
|
|
34
|
+
if (count <= 0)
|
|
35
|
+
return 0;
|
|
36
|
+
let total = separator * (count - 1);
|
|
37
|
+
for (let i = 0; i < count; i += 1)
|
|
38
|
+
total += clauses[i] ?? 0;
|
|
39
|
+
return total;
|
|
40
|
+
}
|
|
41
|
+
export function planRunRow(input) {
|
|
42
|
+
const inner = Math.max(0, width(input.cols) - RUN_ROW_LEAD);
|
|
43
|
+
const natural = width(input.labelCols);
|
|
44
|
+
const separator = width(input.separatorCols);
|
|
45
|
+
const chipCols = width(input.chipCols);
|
|
46
|
+
const clauses = input.hintClauseCols.map(width);
|
|
47
|
+
const total = clauses.length;
|
|
48
|
+
const labelOnly = {
|
|
49
|
+
labelCols: Math.min(natural, inner), hintClauses: 0, chip: false,
|
|
50
|
+
};
|
|
51
|
+
if (total < RUN_ROW_REQUIRED_CLAUSES)
|
|
52
|
+
return labelOnly;
|
|
53
|
+
// Tier 1: everything fits; the chip is the first thing to go.
|
|
54
|
+
const everything = natural + separator + clausesWidth(clauses, total, separator);
|
|
55
|
+
if (everything <= inner) {
|
|
56
|
+
const chip = chipCols > 0 && everything + RUN_ROW_CHIP_GAP + chipCols <= inner;
|
|
57
|
+
return { labelCols: natural, hintClauses: total, chip };
|
|
58
|
+
}
|
|
59
|
+
// Tier 2: drop clauses from the tail, but never below the required two; only the
|
|
60
|
+
// label may be squeezed (down to its minimum) to make the remaining clauses fit.
|
|
61
|
+
for (let kept = total - 1; kept >= RUN_ROW_REQUIRED_CLAUSES; kept -= 1) {
|
|
62
|
+
const available = inner - separator - clausesWidth(clauses, kept, separator);
|
|
63
|
+
if (available >= RUN_ROW_MIN_LABEL_COLS) {
|
|
64
|
+
return { labelCols: Math.min(natural, available), hintClauses: kept, chip: false };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Tier 3 (defensive, below ~40 columns): the label alone. The status bar's own
|
|
68
|
+
// `Esc x2 interrupt` carries the urgent hint at this width.
|
|
69
|
+
return labelOnly;
|
|
70
|
+
}
|
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Plain-text session rendering (spec §4.4). Pure, colorless, ANSI-free, so the
|
|
3
|
-
* exit replay can be piped, diffed, or pasted into an issue.
|
|
4
|
-
*
|
|
5
|
-
* Used only by the full-screen exit replay: inline mode already left the real
|
|
6
|
-
* transcript in the terminal's native scrollback, and replaying there would
|
|
7
|
-
* simply print everything twice.
|
|
8
|
-
*/
|
|
9
1
|
import type { Entry, UsageTotal } from '../agent/reducer.js';
|
|
10
2
|
import type { Glyphs } from './glyphs.js';
|
|
11
3
|
export interface TranscriptTextOptions {
|
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Plain-text session rendering (spec §4.4). Pure, colorless, ANSI-free, so the
|
|
3
|
-
* exit replay can be piped, diffed, or pasted into an issue.
|
|
4
|
-
*
|
|
5
|
-
* Used only by the full-screen exit replay: inline mode already left the real
|
|
6
|
-
* transcript in the terminal's native scrollback, and replaying there would
|
|
7
|
-
* simply print everything twice.
|
|
8
|
-
*/
|
|
9
1
|
import { formatCost, formatDuration, formatTokens, promptTokensOf } from '../agent/usage.js';
|
|
10
2
|
import { formatRetryLine } from '../agent/retry-view.js';
|
|
11
3
|
const DEFAULT_MAX_ENTRIES = 200;
|
|
@@ -40,53 +40,7 @@ export declare const MOUSE_NOTICE_VERSION = 1;
|
|
|
40
40
|
* that offered only `/plan`, recorded back when this was a boolean.
|
|
41
41
|
*/
|
|
42
42
|
export declare const VT_INPUT_NOTICE_VERSION = 1;
|
|
43
|
-
|
|
44
|
-
* The `shift-tab-and-mouse-wheel-dead-on-some-terminals` notice (F1'). Shown at
|
|
45
|
-
* most once per `VT_INPUT_NOTICE_VERSION`, and only on a Windows console that
|
|
46
|
-
* cannot deliver either input — see `ui/win-vt-input.ts` for why that is a
|
|
47
|
-
* property of the Node version rather than of the terminal.
|
|
48
|
-
*
|
|
49
|
-
* IT NAMES WHAT THE KEY DOES NOW, not merely that it is unavailable, and that
|
|
50
|
-
* is the load-bearing half of the text. `Shift+Tab` on these machines is not
|
|
51
|
-
* inert: the modifier is lost inside libuv, so Ink sees an ordinary `Tab` and
|
|
52
|
-
* the `/` palette or an `@` popup completes its selection over the user's
|
|
53
|
-
* draft. A user told only "this key does not work" keeps pressing it and keeps
|
|
54
|
-
* losing text without ever connecting the two.
|
|
55
|
-
*
|
|
56
|
-
* THE FALLBACK KEY COMES BEFORE `/plan` IN BOTH BRANCHES, and it is named from
|
|
57
|
-
* `MODE_TOGGLE_KEYS` rather than spelled out, so the four consumers of that
|
|
58
|
-
* constant cannot drift apart. This notice is the last one of them to be wired
|
|
59
|
-
* up, and it is also the only channel that reaches the affected user without
|
|
60
|
-
* being asked to: the composer hint does not exist at all in inline mode and is
|
|
61
|
-
* switched off by a short terminal or `hints: false` in full-screen, and
|
|
62
|
-
* `/help` has to be typed by someone whose current belief is "the key does
|
|
63
|
-
* nothing" rather than "I should read the help". Ordering follows cost — one
|
|
64
|
-
* keystroke before four and a return.
|
|
65
|
-
*
|
|
66
|
-
* `Shift+Up` / `Shift+Down` is the scroll workaround named here because it is
|
|
67
|
-
* the only one PROVEN to survive: both Node versions emit `\x1b[1;2A` for it,
|
|
68
|
-
* byte for byte, in the probe data. `PgUp` / `PgDn` is expected to work too but
|
|
69
|
-
* was never injected, so it is left out rather than promised.
|
|
70
|
-
*
|
|
71
|
-
* THE WHEEL HALF IS FULL-SCREEN ONLY, and dropping it inline is not a detail.
|
|
72
|
-
* `Shift+Tab` is broken in both modes — the modifier dies inside libuv, well
|
|
73
|
-
* below anything this app chooses — but the wheel is only ours to lose in
|
|
74
|
-
* full-screen: inline never asks the console to report it (`mode` is a conjunct
|
|
75
|
-
* of `cli.tsx::wantMouse`), so the wheel goes on scrolling the terminal's own
|
|
76
|
-
* scrollback exactly as it always has. And `Shift+Up` / `Shift+Down` are handled
|
|
77
|
-
* inside `App`'s `if (fullscreen)` branch, so recommending them inline names a
|
|
78
|
-
* key that does nothing. Telling an inline user their working wheel is dead and
|
|
79
|
-
* then handing them an inert workaround is the same failure this notice exists
|
|
80
|
-
* to end — advice about a mode that is not running — merely pointed the other
|
|
81
|
-
* way.
|
|
82
|
-
*
|
|
83
|
-
* EXPORTED FOR ITS TEST, unlike the two notices above it. Asserting this text
|
|
84
|
-
* through a rendered frame does not work: the transcript wraps a notice at two
|
|
85
|
-
* columns wider than it displays it, so any phrase landing on a wrap boundary
|
|
86
|
-
* loses a character or two on the way to `lastFrame()` and the assertion fails
|
|
87
|
-
* for a reason that has nothing to do with the text.
|
|
88
|
-
*/
|
|
89
|
-
export declare function vtInputDeadNotice(nodeVersion: string, fullscreen: boolean): string;
|
|
43
|
+
export declare function vtInputDeadNotice(nodeVersion: string): string;
|
|
90
44
|
/**
|
|
91
45
|
* `{ requested, resolved }` when the raise happened, `undefined` otherwise —
|
|
92
46
|
* i.e. `cfg.transcriptRetainRequested` and `cfg.transcriptRetain`.
|
|
@@ -132,16 +86,6 @@ export interface MouseNoticeOptions {
|
|
|
132
86
|
export interface VtInputNoticeOptions {
|
|
133
87
|
/** `process.versions.node`, quoted back so the user can act on it. */
|
|
134
88
|
nodeVersion: string;
|
|
135
|
-
/**
|
|
136
|
-
* Whether this run owns the alternate screen, i.e. `App`'s own `fullscreen`.
|
|
137
|
-
*
|
|
138
|
-
* Selects which half of the text applies: inline keeps the wheel and loses the
|
|
139
|
-
* full-screen scroll keys, so it is told about `Shift+Tab` and nothing else
|
|
140
|
-
* (see `vtInputDeadNotice`). Taken from the caller rather than re-derived here
|
|
141
|
-
* for the same reason the version is — one source, no chance of the notice and
|
|
142
|
-
* the renderer disagreeing about which mode is running.
|
|
143
|
-
*/
|
|
144
|
-
fullscreen: boolean;
|
|
145
89
|
/**
|
|
146
90
|
* Record that `VT_INPUT_NOTICE_VERSION` was shown (`state.json`). Called once,
|
|
147
91
|
* after dispatch — and it must write that constant, not `true`: the gate
|
|
@@ -80,61 +80,11 @@ function retainRaisedNotice(requested, resolved) {
|
|
|
80
80
|
* that offered only `/plan`, recorded back when this was a boolean.
|
|
81
81
|
*/
|
|
82
82
|
export const VT_INPUT_NOTICE_VERSION = 1;
|
|
83
|
-
|
|
84
|
-
* The `shift-tab-and-mouse-wheel-dead-on-some-terminals` notice (F1'). Shown at
|
|
85
|
-
* most once per `VT_INPUT_NOTICE_VERSION`, and only on a Windows console that
|
|
86
|
-
* cannot deliver either input — see `ui/win-vt-input.ts` for why that is a
|
|
87
|
-
* property of the Node version rather than of the terminal.
|
|
88
|
-
*
|
|
89
|
-
* IT NAMES WHAT THE KEY DOES NOW, not merely that it is unavailable, and that
|
|
90
|
-
* is the load-bearing half of the text. `Shift+Tab` on these machines is not
|
|
91
|
-
* inert: the modifier is lost inside libuv, so Ink sees an ordinary `Tab` and
|
|
92
|
-
* the `/` palette or an `@` popup completes its selection over the user's
|
|
93
|
-
* draft. A user told only "this key does not work" keeps pressing it and keeps
|
|
94
|
-
* losing text without ever connecting the two.
|
|
95
|
-
*
|
|
96
|
-
* THE FALLBACK KEY COMES BEFORE `/plan` IN BOTH BRANCHES, and it is named from
|
|
97
|
-
* `MODE_TOGGLE_KEYS` rather than spelled out, so the four consumers of that
|
|
98
|
-
* constant cannot drift apart. This notice is the last one of them to be wired
|
|
99
|
-
* up, and it is also the only channel that reaches the affected user without
|
|
100
|
-
* being asked to: the composer hint does not exist at all in inline mode and is
|
|
101
|
-
* switched off by a short terminal or `hints: false` in full-screen, and
|
|
102
|
-
* `/help` has to be typed by someone whose current belief is "the key does
|
|
103
|
-
* nothing" rather than "I should read the help". Ordering follows cost — one
|
|
104
|
-
* keystroke before four and a return.
|
|
105
|
-
*
|
|
106
|
-
* `Shift+Up` / `Shift+Down` is the scroll workaround named here because it is
|
|
107
|
-
* the only one PROVEN to survive: both Node versions emit `\x1b[1;2A` for it,
|
|
108
|
-
* byte for byte, in the probe data. `PgUp` / `PgDn` is expected to work too but
|
|
109
|
-
* was never injected, so it is left out rather than promised.
|
|
110
|
-
*
|
|
111
|
-
* THE WHEEL HALF IS FULL-SCREEN ONLY, and dropping it inline is not a detail.
|
|
112
|
-
* `Shift+Tab` is broken in both modes — the modifier dies inside libuv, well
|
|
113
|
-
* below anything this app chooses — but the wheel is only ours to lose in
|
|
114
|
-
* full-screen: inline never asks the console to report it (`mode` is a conjunct
|
|
115
|
-
* of `cli.tsx::wantMouse`), so the wheel goes on scrolling the terminal's own
|
|
116
|
-
* scrollback exactly as it always has. And `Shift+Up` / `Shift+Down` are handled
|
|
117
|
-
* inside `App`'s `if (fullscreen)` branch, so recommending them inline names a
|
|
118
|
-
* key that does nothing. Telling an inline user their working wheel is dead and
|
|
119
|
-
* then handing them an inert workaround is the same failure this notice exists
|
|
120
|
-
* to end — advice about a mode that is not running — merely pointed the other
|
|
121
|
-
* way.
|
|
122
|
-
*
|
|
123
|
-
* EXPORTED FOR ITS TEST, unlike the two notices above it. Asserting this text
|
|
124
|
-
* through a rendered frame does not work: the transcript wraps a notice at two
|
|
125
|
-
* columns wider than it displays it, so any phrase landing on a wrap boundary
|
|
126
|
-
* loses a character or two on the way to `lastFrame()` and the assertion fails
|
|
127
|
-
* for a reason that has nothing to do with the text.
|
|
128
|
-
*/
|
|
129
|
-
export function vtInputDeadNotice(nodeVersion, fullscreen) {
|
|
83
|
+
export function vtInputDeadNotice(nodeVersion) {
|
|
130
84
|
const cause = `Node ${nodeVersion} on Windows does not turn on the console's VT input mode, so `;
|
|
131
85
|
const cost = 'it will not switch mode, and with the / palette or an @ popup open it completes that ' +
|
|
132
86
|
'instead, overwriting your draft. ';
|
|
133
87
|
const toggle = `Press ${MODE_TOGGLE_KEYS.fallback} to switch mode instead (or /plan)`;
|
|
134
|
-
if (!fullscreen) {
|
|
135
|
-
return (`${cause}Shift+Tab never arrives: it comes through as a PLAIN TAB - ${cost}` +
|
|
136
|
-
`${toggle}. Node 22.17.0+ (or 24.2.0+) restores it.`);
|
|
137
|
-
}
|
|
138
88
|
return (`${cause}two keys never arrive: the wheel sends nothing at all, and Shift+Tab arrives ` +
|
|
139
89
|
`as a PLAIN TAB - ${cost}${toggle}, and Shift+Up / Shift+Down to scroll. ` +
|
|
140
90
|
'Node 22.17.0+ (or 24.2.0+) restores both.');
|
|
@@ -199,7 +149,6 @@ export function useStartupNotices(dispatch, mouseNotice, retainNotice, vtInputNo
|
|
|
199
149
|
const vtNoticeRef = useRef(vtInputNotice);
|
|
200
150
|
vtNoticeRef.current = vtInputNotice;
|
|
201
151
|
const vtNodeVersion = vtInputNotice?.nodeVersion;
|
|
202
|
-
const vtFullscreen = vtInputNotice?.fullscreen ?? false;
|
|
203
152
|
const vtNoticeShown = useRef(false);
|
|
204
153
|
useEffect(() => {
|
|
205
154
|
if (vtNodeVersion === undefined || vtNoticeShown.current)
|
|
@@ -210,10 +159,10 @@ export function useStartupNotices(dispatch, mouseNotice, retainNotice, vtInputNo
|
|
|
210
159
|
dispatch({
|
|
211
160
|
type: 'notice',
|
|
212
161
|
level: 'warn',
|
|
213
|
-
text: vtInputDeadNotice(vtNodeVersion
|
|
162
|
+
text: vtInputDeadNotice(vtNodeVersion),
|
|
214
163
|
});
|
|
215
164
|
vtNoticeRef.current?.onSeen();
|
|
216
|
-
}, [vtNodeVersion,
|
|
165
|
+
}, [vtNodeVersion, dispatch]);
|
|
217
166
|
// A `warn` notice rather than a toast: it is about a value the user typed, so
|
|
218
167
|
// it belongs in the transcript where it can be scrolled back to, not in a row
|
|
219
168
|
// that expires. DEPENDS ON THE TWO SCALARS, never on the options object —
|
|
@@ -32,7 +32,7 @@ export declare const OVERLAY_PAGE = 8;
|
|
|
32
32
|
export interface WheelRoutingOptions {
|
|
33
33
|
isPointerCaptured?: () => boolean;
|
|
34
34
|
isActive?: () => boolean;
|
|
35
|
-
/** Absent when mouse support is off,
|
|
35
|
+
/** Absent when mouse support is off, or on a non-TTY. */
|
|
36
36
|
mouseSource?: MouseSource;
|
|
37
37
|
/** Read at EVENT time for the routing branch, and again at FLUSH time (P1-3). */
|
|
38
38
|
getOverlay: () => Overlay | null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aragon-agent/cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.9",
|
|
4
4
|
"description": "AragonAgent CLI — a Claude-Code / Codex-style interactive terminal UI (TUI) on top of the @aragon-agent/core engine. Installable and runnable via npm / npx.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "AragonAgent contributors",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"prepublishOnly": "npm run build"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@aragon-agent/core": "^0.2.
|
|
59
|
+
"@aragon-agent/core": "^0.2.21",
|
|
60
60
|
"chalk": "^5.6.2",
|
|
61
61
|
"cli-highlight": "^2.0.0",
|
|
62
62
|
"commander": "^12.1.0",
|