@timurproko/a1 0.2.5-dev.698 → 0.2.5
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/dist/app/session-shell/session-shell.js +9 -8
- package/dist/composition/owned-ui.js +2 -0
- package/dist/contracts/presentation/index.d.ts +6 -1
- package/dist/contracts/presentation/index.js +4 -2
- package/dist/features/owned-ui/resources/release-notes.json +4 -0
- package/dist/features/owned-ui/settings-app.d.ts +1 -1
- package/dist/features/owned-ui/settings-app.js +334 -63
- package/dist/integrations/pi/components/models-dialog.js +2 -2
- package/dist/integrations/pi/components/shell-editor-autocomplete.js +40 -2
- package/dist/integrations/pi/components/skills-dialog.js +2 -2
- package/dist/integrations/pi/components/upstream/components/owned-editor.d.ts +4 -2
- package/dist/integrations/pi/components/upstream/components/owned-editor.js +48 -12
- package/dist/integrations/pi/components/upstream/components/session-selector.js +14 -14
- package/dist/integrations/pi/components/upstream/components/thinking-selector.d.ts +5 -4
- package/dist/integrations/pi/components/upstream/components/thinking-selector.js +6 -4
- package/dist/integrations/pi/components/upstream/components/tree-selector.d.ts +7 -6
- package/dist/integrations/pi/components/upstream/components/tree-selector.js +24 -18
- package/dist/native/darwin-arm64/manifest.json +1 -1
- package/dist/native/linux-x64/manifest.json +1 -1
- package/dist/native/win32-x64/manifest.json +2 -2
- package/dist/native/win32-x64/process-guardian.exe +0 -0
- package/dist/ui/components/dialog-panel.d.ts +15 -0
- package/dist/ui/components/dialog-panel.js +50 -3
- package/dist/ui/components/index.d.ts +3 -3
- package/dist/ui/components/index.js +2 -2
- package/dist/ui/components/line-input.d.ts +2 -0
- package/dist/ui/components/line-input.js +2 -2
- package/dist/ui/components/prompt-input.d.ts +2 -2
- package/dist/ui/components/prompt-input.js +5 -5
- package/dist/ui/components/shortcut-hints.d.ts +8 -3
- package/dist/ui/components/shortcut-hints.js +25 -5
- package/dist/ui/components/shortcuts.d.ts +1 -1
- package/dist/ui/components/shortcuts.js +4 -0
- package/dist/ui/components/value-menu.js +3 -1
- package/dist/ui/settings/manager.d.ts +1 -0
- package/dist/ui/settings/manager.js +9 -3
- package/docs/releases/0.2.5.md +35 -0
- package/package.json +1 -1
|
@@ -209,7 +209,7 @@ export function caretCell(text) {
|
|
|
209
209
|
/** The input row as the reference draws one, padded to exactly the width. */
|
|
210
210
|
export function renderInputRow(input, width, options = {}) {
|
|
211
211
|
const presentation = new PromptInput(options.theme);
|
|
212
|
-
const view = input.view(Math.max(0, width - presentation.geometry(width).prefixWidth));
|
|
212
|
+
const view = input.view(Math.max(0, width - presentation.geometry(width, 0, options.promptGlyph).prefixWidth));
|
|
213
213
|
const placeholder = options.placeholder ?? "";
|
|
214
214
|
const empty = view.text.length === 0 && placeholder.length > 0;
|
|
215
215
|
const before = view.text.slice(0, view.caretColumn);
|
|
@@ -220,5 +220,5 @@ export function renderInputRow(input, width, options = {}) {
|
|
|
220
220
|
const body = empty
|
|
221
221
|
? `${caretCell(placeholder.slice(0, 1))}${faint(placeholder.slice(1))}`
|
|
222
222
|
: `${before}${caretCell(under)}${after}`;
|
|
223
|
-
return { lines: presentation.render(width, () => ({ rows: [body] }), options.ruled) };
|
|
223
|
+
return { lines: presentation.render(width, () => ({ rows: [body] }), options.ruled, 0, options.promptGlyph) };
|
|
224
224
|
}
|
|
@@ -21,12 +21,12 @@ export declare class PromptInput {
|
|
|
21
21
|
readonly metrics: PromptInputMetrics;
|
|
22
22
|
constructor(theme?: Pick<UiTheme, "fg">, metrics?: PromptInputMetrics);
|
|
23
23
|
styleRule(text: string): string;
|
|
24
|
-
geometry(width: number, padding?: number): {
|
|
24
|
+
geometry(width: number, padding?: number, promptGlyph?: string): {
|
|
25
25
|
prefixWidth: number;
|
|
26
26
|
innerWidth: number;
|
|
27
27
|
paddingX: number;
|
|
28
28
|
contentWidth: number;
|
|
29
29
|
layoutWidth: number;
|
|
30
30
|
};
|
|
31
|
-
render(width: number, renderBody: (innerWidth: number) => PromptInputBody, ruled?: boolean, padding?: number): string[];
|
|
31
|
+
render(width: number, renderBody: (innerWidth: number) => PromptInputBody, ruled?: boolean, padding?: number, promptGlyph?: string): string[];
|
|
32
32
|
}
|
|
@@ -17,8 +17,8 @@ export class PromptInput {
|
|
|
17
17
|
metrics;
|
|
18
18
|
constructor(theme = PLAIN_THEME, metrics = { measure: displayWidth, truncate: truncateToWidth }) { this.theme = theme; this.metrics = metrics; }
|
|
19
19
|
styleRule(text) { return promptRuleText(text); }
|
|
20
|
-
geometry(width, padding = 0) {
|
|
21
|
-
const prefixWidth = Math.min(
|
|
20
|
+
geometry(width, padding = 0, promptGlyph = PROMPT_GLYPH) {
|
|
21
|
+
const prefixWidth = Math.min(this.metrics.measure(promptGlyph), Math.max(0, width));
|
|
22
22
|
// Compatibility: editor wrapping needs room for a two-cell grapheme plus its cursor cell.
|
|
23
23
|
// Lay out against a safe virtual width, then clip only at the shared frame boundary.
|
|
24
24
|
const innerWidth = Math.max(3 + padding * 2, width - prefixWidth);
|
|
@@ -26,17 +26,17 @@ export class PromptInput {
|
|
|
26
26
|
const contentWidth = Math.max(1, innerWidth - paddingX * 2);
|
|
27
27
|
return { prefixWidth, innerWidth, paddingX, contentWidth, layoutWidth: Math.max(1, contentWidth - (paddingX ? 0 : 1)) };
|
|
28
28
|
}
|
|
29
|
-
render(width, renderBody, ruled = true, padding = 0) {
|
|
29
|
+
render(width, renderBody, ruled = true, padding = 0, promptGlyph = PROMPT_GLYPH) {
|
|
30
30
|
if (width <= 0)
|
|
31
31
|
return [];
|
|
32
|
-
const { prefixWidth, innerWidth } = this.geometry(width, padding);
|
|
32
|
+
const { prefixWidth, innerWidth } = this.geometry(width, padding, promptGlyph);
|
|
33
33
|
const body = renderBody(innerWidth);
|
|
34
34
|
const fit = (row) => {
|
|
35
35
|
const clipped = this.metrics.truncate(row, width);
|
|
36
36
|
return clipped + " ".repeat(Math.max(0, width - this.metrics.measure(clipped)));
|
|
37
37
|
};
|
|
38
38
|
const rows = body.rows.map((row, index) => fit(`${index === 0
|
|
39
|
-
? promptArrow(
|
|
39
|
+
? promptArrow(promptGlyph, this.theme)
|
|
40
40
|
: " ".repeat(prefixWidth)}${row}`));
|
|
41
41
|
const rule = (fragment) => fragment === undefined
|
|
42
42
|
? promptRule(width)
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { type SemanticShortcutHint } from "../../contracts/presentation/index.js";
|
|
2
2
|
import type { UiTheme } from "./theme.js";
|
|
3
3
|
export type ShortcutHintEntry = SemanticShortcutHint;
|
|
4
|
+
/**
|
|
5
|
+
* Enforces the owned-dialog hint grammar at the shared rendering boundary.
|
|
6
|
+
* Pinned Pi surfaces use their separate adapter and retain upstream wording.
|
|
7
|
+
*/
|
|
8
|
+
export declare function assertOwnedShortcutHintConventions(entries: readonly ShortcutHintEntry[]): void;
|
|
4
9
|
/** Returns an unstyled modal instruction row for width-aware clipping. */
|
|
5
|
-
export declare function shortcutHintsText(entries: readonly ShortcutHintEntry[], indent?: number): string;
|
|
6
|
-
/** Paints one modal instruction row
|
|
7
|
-
export declare function renderShortcutHints(entries: readonly ShortcutHintEntry[], theme: Pick<UiTheme, "fg">, indent?: number): string;
|
|
10
|
+
export declare function shortcutHintsText(entries: readonly ShortcutHintEntry[], indent?: number, separator?: string): string;
|
|
11
|
+
/** Paints one modal instruction row with shared key/action roles and caller-selected spacing. */
|
|
12
|
+
export declare function renderShortcutHints(entries: readonly ShortcutHintEntry[], theme: Pick<UiTheme, "fg">, indent?: number, separator?: string): string;
|
|
8
13
|
/** Clips preceding guidance first so a final canonical close entry remains complete whenever it fits. */
|
|
9
14
|
export declare function renderShortcutHintsWithClose(entries: readonly ShortcutHintEntry[], theme: Pick<UiTheme, "fg">, width: number, indent?: number): string;
|
|
@@ -1,15 +1,35 @@
|
|
|
1
1
|
import { DIALOG_CLOSE_SHORTCUT_HINT, renderSemanticShortcutHints, } from "../../contracts/presentation/index.js";
|
|
2
2
|
import { displayWidth, truncateToWidth } from "./text.js";
|
|
3
|
+
/**
|
|
4
|
+
* Enforces the owned-dialog hint grammar at the shared rendering boundary.
|
|
5
|
+
* Pinned Pi surfaces use their separate adapter and retain upstream wording.
|
|
6
|
+
*/
|
|
7
|
+
export function assertOwnedShortcutHintConventions(entries) {
|
|
8
|
+
for (const entry of entries) {
|
|
9
|
+
if (entry.key === undefined || entry.key.trim().length === 0)
|
|
10
|
+
continue;
|
|
11
|
+
if (entry.key !== entry.key.trim())
|
|
12
|
+
throw new TypeError("owned shortcut hint keys must not have surrounding whitespace");
|
|
13
|
+
if (entry.action !== entry.action.trim() || entry.action.length === 0) {
|
|
14
|
+
throw new TypeError("owned shortcut hint actions must be nonempty and have no surrounding whitespace");
|
|
15
|
+
}
|
|
16
|
+
if (/^to(?:\s|$)/iu.test(entry.action)) {
|
|
17
|
+
throw new TypeError(`owned shortcut hint actions omit connective "to": ${entry.key} ${entry.action}`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
3
21
|
/** Returns an unstyled modal instruction row for width-aware clipping. */
|
|
4
|
-
export function shortcutHintsText(entries, indent = 0) {
|
|
5
|
-
|
|
22
|
+
export function shortcutHintsText(entries, indent = 0, separator = " ") {
|
|
23
|
+
assertOwnedShortcutHintConventions(entries);
|
|
24
|
+
return renderSemanticShortcutHints(entries, { key: text => text, action: text => text }, indent, separator);
|
|
6
25
|
}
|
|
7
|
-
/** Paints one modal instruction row
|
|
8
|
-
export function renderShortcutHints(entries, theme, indent = 0) {
|
|
26
|
+
/** Paints one modal instruction row with shared key/action roles and caller-selected spacing. */
|
|
27
|
+
export function renderShortcutHints(entries, theme, indent = 0, separator = " ") {
|
|
28
|
+
assertOwnedShortcutHintConventions(entries);
|
|
9
29
|
return renderSemanticShortcutHints(entries, {
|
|
10
30
|
key: text => theme.fg("dim", text),
|
|
11
31
|
action: text => theme.fg("muted", text),
|
|
12
|
-
}, indent);
|
|
32
|
+
}, indent, separator);
|
|
13
33
|
}
|
|
14
34
|
/** Clips preceding guidance first so a final canonical close entry remains complete whenever it fits. */
|
|
15
35
|
export function renderShortcutHintsWithClose(entries, theme, width, indent = 0) {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* assembled, and any listing is generated from the same declarations — so a
|
|
5
5
|
* listed shortcut is one dispatch would actually invoke.
|
|
6
6
|
*/
|
|
7
|
-
import type
|
|
7
|
+
import { type ShortcutHintEntry } from "./shortcut-hints.js";
|
|
8
8
|
export interface ShortcutDeclaration {
|
|
9
9
|
/** Key token, for example `up`, `shift+down`, `ctrl+c`, or a literal character. */
|
|
10
10
|
readonly key: string;
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* assembled, and any listing is generated from the same declarations — so a
|
|
5
5
|
* listed shortcut is one dispatch would actually invoke.
|
|
6
6
|
*/
|
|
7
|
+
import { assertOwnedShortcutHintConventions } from "./shortcut-hints.js";
|
|
7
8
|
export const GLOBAL_SCOPE = "global";
|
|
8
9
|
function overlaps(left, right) {
|
|
9
10
|
return left === right || left === GLOBAL_SCOPE || right === GLOBAL_SCOPE;
|
|
@@ -45,6 +46,9 @@ export class ShortcutRegistry {
|
|
|
45
46
|
#declarations = [];
|
|
46
47
|
#actions = new Map();
|
|
47
48
|
declare(declaration, action) {
|
|
49
|
+
if (declaration.hint !== undefined) {
|
|
50
|
+
assertOwnedShortcutHintConventions([{ key: declaration.hint.keys, action: declaration.hint.does }]);
|
|
51
|
+
}
|
|
48
52
|
this.#declarations.push(declaration);
|
|
49
53
|
this.#actions.set(`${declaration.scope}\u0000${declaration.key}`, action);
|
|
50
54
|
}
|
|
@@ -9,7 +9,9 @@ export function valueMenuFrame(state, anchor, layout) {
|
|
|
9
9
|
? below
|
|
10
10
|
: Math.max(bodyTop, anchor.screenRow - state.choices.length);
|
|
11
11
|
const width = Math.max(...state.choices.map(choice => displayWidth(choice) + 4), 6);
|
|
12
|
-
|
|
12
|
+
// Invariant: each row reserves two cells for its effective-value mark. Place those
|
|
13
|
+
// cells before the anchor so visible choice text starts in the source value column.
|
|
14
|
+
const column = Math.min(Math.max(0, anchor.valueColumn - 2), Math.max(0, layout.surfaceWidth - width - layout.reservedRight));
|
|
13
15
|
return { top, column, width, rows: state.choices.length };
|
|
14
16
|
}
|
|
15
17
|
/** Draws the menu over the rows behind it, leaving them otherwise untouched. */
|
|
@@ -12,6 +12,7 @@ export interface OwnedSettingsManagerOptions {
|
|
|
12
12
|
readonly agent?: AgentSettingsPort | null;
|
|
13
13
|
readonly agentProvider?: () => AgentSettingsPort | null;
|
|
14
14
|
readonly hiddenAgentSettingIds?: readonly string[];
|
|
15
|
+
readonly agentSettingLabelOverrides?: Readonly<Record<string, string>>;
|
|
15
16
|
}
|
|
16
17
|
export interface OwnedUiSettingsChangeOutcome {
|
|
17
18
|
readonly status: "applied" | "deferred" | "unavailable" | "failed";
|
|
@@ -21,6 +21,7 @@ export class OwnedSettingsManager {
|
|
|
21
21
|
#agentProvider;
|
|
22
22
|
#listeners = new Set();
|
|
23
23
|
#hiddenAgentSettingIds;
|
|
24
|
+
#agentSettingLabelOverrides;
|
|
24
25
|
#resolution;
|
|
25
26
|
#agentSnapshot = null;
|
|
26
27
|
#pending = new Map();
|
|
@@ -35,6 +36,7 @@ export class OwnedSettingsManager {
|
|
|
35
36
|
this.#agent = options.agent ?? null;
|
|
36
37
|
this.#agentProvider = options.agentProvider ?? null;
|
|
37
38
|
this.#hiddenAgentSettingIds = new Set(options.hiddenAgentSettingIds ?? []);
|
|
39
|
+
this.#agentSettingLabelOverrides = { ...(options.agentSettingLabelOverrides ?? {}) };
|
|
38
40
|
this.#resolution = this.read();
|
|
39
41
|
for (const setting of this.#resolution.settings) {
|
|
40
42
|
if (setting.declaration.application === "restart")
|
|
@@ -83,9 +85,13 @@ export class OwnedSettingsManager {
|
|
|
83
85
|
sections() {
|
|
84
86
|
return buildOwnedUiSettingsSections({ resolution: this.#resolution, agent: this.#agentSnapshot }).map(section => ({
|
|
85
87
|
...section,
|
|
86
|
-
entries: section.entries.map(entry =>
|
|
87
|
-
|
|
88
|
-
|
|
88
|
+
entries: section.entries.map(entry => {
|
|
89
|
+
if (entry.backend === "a1" && this.#restartEffective.has(entry.id)) {
|
|
90
|
+
return { ...entry, effectiveValue: this.#restartEffective.get(entry.id) };
|
|
91
|
+
}
|
|
92
|
+
const label = entry.backend === "agent" ? this.#agentSettingLabelOverrides[entry.id] : undefined;
|
|
93
|
+
return label === undefined ? entry : { ...entry, label };
|
|
94
|
+
}),
|
|
89
95
|
}));
|
|
90
96
|
}
|
|
91
97
|
/**
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
## [0.2.5] - 2026-10-07
|
|
2
|
+
|
|
3
|
+
### New Features
|
|
4
|
+
|
|
5
|
+
- show session info full screen ([#680](https://github.com/timurproko/a1/pull/680))
|
|
6
|
+
- redesign session tree dialog ([#682](https://github.com/timurproko/a1/pull/682))
|
|
7
|
+
- add name command input dialog ([#694](https://github.com/timurproko/a1/pull/694))
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- refine animated separator ([#681](https://github.com/timurproko/a1/pull/681))
|
|
12
|
+
- upgrade pinned Pi to 1.0.4 ([#683](https://github.com/timurproko/a1/pull/683))
|
|
13
|
+
- unify selection treatment ([#686](https://github.com/timurproko/a1/pull/686))
|
|
14
|
+
- align project trust dialogs ([#687](https://github.com/timurproko/a1/pull/687))
|
|
15
|
+
- standardize share dialog ([#689](https://github.com/timurproko/a1/pull/689))
|
|
16
|
+
- align Resume Session dialog ([#693](https://github.com/timurproko/a1/pull/693))
|
|
17
|
+
- unify dialog close hints ([#695](https://github.com/timurproko/a1/pull/695))
|
|
18
|
+
- accent model scope markers ([#696](https://github.com/timurproko/a1/pull/696))
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- wrap session file after label ([#684](https://github.com/timurproko/a1/pull/684))
|
|
23
|
+
- align thinking markers with models ([#685](https://github.com/timurproko/a1/pull/685))
|
|
24
|
+
- place new-session notice above prompt ([#688](https://github.com/timurproko/a1/pull/688))
|
|
25
|
+
- close dialogs with Ctrl+C ([#690](https://github.com/timurproko/a1/pull/690))
|
|
26
|
+
- restore suggestion after Backspace ([#691](https://github.com/timurproko/a1/pull/691))
|
|
27
|
+
- cycle dialog filters backward ([#692](https://github.com/timurproko/a1/pull/692))
|
|
28
|
+
- avoid initial value-menu highlight ([#697](https://github.com/timurproko/a1/pull/697))
|
|
29
|
+
- keep session root expanded ([#698](https://github.com/timurproko/a1/pull/698))
|
|
30
|
+
- hide skill prefixes in collapsed menu ([#699](https://github.com/timurproko/a1/pull/699))
|
|
31
|
+
- omit space after command completion ([#700](https://github.com/timurproko/a1/pull/700))
|
|
32
|
+
- stabilize values and add undo ([#701](https://github.com/timurproko/a1/pull/701))
|
|
33
|
+
- standardize typing search hints ([#702](https://github.com/timurproko/a1/pull/702))
|
|
34
|
+
- show tree time toggle state ([#703](https://github.com/timurproko/a1/pull/703))
|
|
35
|
+
- refine resume search hints ([#704](https://github.com/timurproko/a1/pull/704))
|
package/package.json
CHANGED