@timurproko/a1 0.1.8-dev.527 → 0.1.8-dev.536
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-root.d.ts +1 -0
- package/dist/app/session-shell/session-shell-root.js +3 -1
- package/dist/app/session-shell/session-shell.d.ts +1 -1
- package/dist/app/session-shell/session-shell.js +10 -4
- package/dist/composition/owned-ui.js +4 -3
- package/dist/composition/settings-route-host.d.ts +5 -9
- package/dist/composition/settings-route-host.js +2 -2
- package/dist/contracts/owned-ui/model.d.ts +4 -0
- package/dist/contracts/owned-ui/validation.js +25 -0
- package/dist/features/owned-ui/index.d.ts +1 -1
- package/dist/features/owned-ui/reference-screen-app.d.ts +9 -3
- package/dist/features/owned-ui/reference-screen-app.js +68 -20
- package/dist/features/owned-ui/settings-app.js +69 -24
- package/dist/foundation/startup/startup-descriptor.js +2 -2
- package/dist/integrations/pi/components/index.d.ts +3 -1
- package/dist/integrations/pi/components/index.js +2 -1
- package/dist/integrations/pi/components/shell-editor-autocomplete.d.ts +9 -1
- package/dist/integrations/pi/components/shell-editor-autocomplete.js +10 -9
- package/dist/integrations/pi/components/shell-footer-status.d.ts +1 -1
- package/dist/integrations/pi/components/shell-footer-status.js +2 -2
- package/dist/integrations/pi/components/shell-hotkey-sections.d.ts +7 -0
- package/dist/integrations/pi/components/shell-hotkey-sections.js +29 -0
- package/dist/integrations/pi/components/shell-presenters-info.d.ts +1 -0
- package/dist/integrations/pi/components/shell-presenters-info.js +1 -1
- package/dist/integrations/pi/components/shell-selectors-dialogs.d.ts +0 -1
- package/dist/integrations/pi/components/shell-selectors-dialogs.js +1 -7
- package/dist/integrations/pi/components/thinking-selector-dialog.d.ts +8 -0
- package/dist/integrations/pi/components/thinking-selector-dialog.js +22 -0
- package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.js +1 -1
- package/dist/integrations/pi/components/upstream/assets/earendil-image.json +2 -2
- package/dist/integrations/pi/components/upstream/components/countdown-timer.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/daxnuts.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/daxnuts.js +1 -1
- package/dist/integrations/pi/components/upstream/components/earendil-announcement.js +1 -1
- package/dist/integrations/pi/components/upstream/components/extension-editor.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/extension-editor.js +1 -1
- package/dist/integrations/pi/components/upstream/components/mermaid.js +1 -1
- package/dist/integrations/pi/components/upstream/components/owned-editor.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/owned-editor.js +1 -1
- package/dist/integrations/pi/components/upstream/components/scoped-models-selector.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/session-footer.d.ts +2 -1
- package/dist/integrations/pi/components/upstream/components/session-footer.js +22 -11
- package/dist/integrations/pi/components/upstream/components/session-selector-search.js +1 -1
- package/dist/integrations/pi/components/upstream/components/session-selector.js +1 -1
- package/dist/integrations/pi/components/upstream/components/skill-invocation-message.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/skill-invocation-message.js +1 -1
- package/dist/integrations/pi/components/upstream/components/status-indicator.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/status-indicator.js +1 -1
- package/dist/integrations/pi/components/upstream/components/thinking-selector.d.ts +33 -0
- package/dist/integrations/pi/components/upstream/components/thinking-selector.js +140 -0
- package/dist/integrations/pi/components/upstream/components/tool-execution.js +1 -1
- package/dist/integrations/pi/components/upstream/components/tree-selector.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/tree-selector.js +8 -1
- package/dist/integrations/pi/components/upstream/components/trust-selector.js +1 -1
- package/dist/integrations/pi/components/upstream/external-editor.js +1 -1
- package/dist/integrations/pi/components/upstream/history/editor-core.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/history/editor-core.js +1 -1
- package/dist/integrations/pi/components/upstream/history/kill-ring.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/history/kill-ring.js +1 -1
- package/dist/integrations/pi/components/upstream/history/printable-key.js +1 -1
- package/dist/integrations/pi/components/upstream/history/text-helpers.js +1 -1
- package/dist/integrations/pi/components/upstream/history/undo-stack.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/history/undo-stack.js +1 -1
- package/dist/integrations/pi/components/upstream/history/word-navigation.js +1 -1
- package/dist/integrations/pi/components/upstream/model-search.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/theme/theme-controller.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/theme/theme.js +1 -1
- package/dist/integrations/pi/engine/adapter.js +1 -0
- package/dist/integrations/pi/engine/repository-pr.d.ts +8 -0
- package/dist/integrations/pi/engine/repository-pr.js +62 -0
- package/dist/integrations/pi/engine/resources/changelog.json +4 -4
- package/dist/integrations/pi/engine/session-runtime.d.ts +5 -0
- package/dist/integrations/pi/engine/session-runtime.js +60 -1
- package/dist/integrations/pi/engine/workflows.d.ts +1 -1
- package/dist/integrations/pi/engine/workflows.js +4 -2
- package/dist/integrations/pi/startup-public.js +43 -37
- package/dist/integrations/pi/startup-public.manifest.json +143 -142
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +1 -1
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.js +1 -1
- 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/product-identity.d.ts +1 -1
- package/dist/product-identity.js +1 -1
- package/dist/product-identity.json +1 -0
- package/dist/runtime-payload-inventory.json +2782 -2662
- package/dist/ui/components/index.d.ts +1 -1
- package/dist/ui/components/list-block.d.ts +10 -6
- package/dist/ui/components/list-block.js +28 -15
- package/dist/ui/components/list-view.d.ts +1 -1
- package/dist/ui/components/list-view.js +4 -2
- package/dist/ui/components/mouse.js +4 -2
- package/dist/ui/components/theme.d.ts +1 -5
- package/dist/ui/components/theme.js +0 -4
- package/dist/ui/components/value-menu.d.ts +3 -1
- package/dist/ui/components/value-menu.js +13 -5
- package/docs/local-worktree-cleanup.md +1 -1
- package/package.json +3 -3
|
@@ -8,7 +8,7 @@ export type { InputRow, InputRowOptions, LineInputOutcome, LineInputView } from
|
|
|
8
8
|
export { PROMPT_GLYPH, PROMPT_PREFIX_WIDTH, PromptInput, promptArrow, promptRule, promptRuleText } from "./prompt-input.js";
|
|
9
9
|
export type { PromptInputBody, PromptInputMetrics } from "./prompt-input.js";
|
|
10
10
|
export { blockJumpTarget, blockRowSpan, clampScroll, indexOfKey, layoutList, maxScrollFor, moveSelection, rowKey, scrollForSelection, selectableIndexes, stickyHeaderFor, topPaddingRows, visibleRowCount, } from "./list-block.js";
|
|
11
|
-
export type { ListLayout, ListRow, ListRowSpan } from "./list-block.js";
|
|
11
|
+
export type { ListLayout, ListLayoutOptions, ListRow, ListRowSpan } from "./list-block.js";
|
|
12
12
|
export { STEPPER_RESERVE, placementFor, regionAt, renderGroupHeader, renderListRow, renderNote, valueColumnFor } from "./list-view.js";
|
|
13
13
|
export type { ListRegion, ListRowPlacement, ListRowState, ListViewRow } from "./list-view.js";
|
|
14
14
|
export { MOUSE_TRACKING_OFF, MOUSE_TRACKING_ON, parseMouseInput, routeMouseInput } from "./mouse.js";
|
|
@@ -37,14 +37,18 @@ export declare function moveSelection<T>(rows: readonly ListRow<T>[], current: n
|
|
|
37
37
|
export declare function blockJumpTarget<T>(rows: readonly ListRow<T>[], current: number, delta: number): number | undefined;
|
|
38
38
|
/** The block containing `index`: its header through the row before the next header. */
|
|
39
39
|
export declare function blockRowSpan<T>(rows: readonly ListRow<T>[], index: number): ListRowSpan;
|
|
40
|
-
/** The header pinned above the body
|
|
40
|
+
/** The header pinned above the body while its content or outgoing spacer is at the top. */
|
|
41
41
|
export declare function stickyHeaderFor<T>(rows: readonly ListRow<T>[], scroll: number): string | undefined;
|
|
42
|
+
export interface ListLayoutOptions {
|
|
43
|
+
/** Settings keeps one opening row; embedded documents can start with their own prelude. */
|
|
44
|
+
readonly topPadding?: boolean;
|
|
45
|
+
}
|
|
42
46
|
/** One blank row above the first group while the list is scrolled to the top. */
|
|
43
|
-
export declare function topPaddingRows(scroll: number): number;
|
|
47
|
+
export declare function topPaddingRows(scroll: number, enabled?: boolean): number;
|
|
44
48
|
/** Rows of content visible after the padding and any pinned header. */
|
|
45
|
-
export declare function visibleRowCount<T>(rows: readonly ListRow<T>[], bodyHeight: number, scroll: number): number;
|
|
46
|
-
export declare function maxScrollFor<T>(rows: readonly ListRow<T>[], bodyHeight: number): number;
|
|
47
|
-
export declare function clampScroll<T>(rows: readonly ListRow<T>[], bodyHeight: number, scroll: number): {
|
|
49
|
+
export declare function visibleRowCount<T>(rows: readonly ListRow<T>[], bodyHeight: number, scroll: number, options?: ListLayoutOptions): number;
|
|
50
|
+
export declare function maxScrollFor<T>(rows: readonly ListRow<T>[], bodyHeight: number, options?: ListLayoutOptions): number;
|
|
51
|
+
export declare function clampScroll<T>(rows: readonly ListRow<T>[], bodyHeight: number, scroll: number, options?: ListLayoutOptions): {
|
|
48
52
|
readonly scroll: number;
|
|
49
53
|
readonly visible: number;
|
|
50
54
|
};
|
|
@@ -63,4 +67,4 @@ export interface ListLayout {
|
|
|
63
67
|
readonly rowIndexes: readonly number[];
|
|
64
68
|
}
|
|
65
69
|
/** Everything a renderer needs for one frame, derived rather than remembered. */
|
|
66
|
-
export declare function layoutList<T>(rows: readonly ListRow<T>[], bodyHeight: number, scroll: number): ListLayout;
|
|
70
|
+
export declare function layoutList<T>(rows: readonly ListRow<T>[], bodyHeight: number, scroll: number, options?: ListLayoutOptions): ListLayout;
|
|
@@ -95,37 +95,37 @@ export function blockRowSpan(rows, index) {
|
|
|
95
95
|
}
|
|
96
96
|
return { from, to };
|
|
97
97
|
}
|
|
98
|
-
/** The header pinned above the body
|
|
98
|
+
/** The header pinned above the body while its content or outgoing spacer is at the top. */
|
|
99
99
|
export function stickyHeaderFor(rows, scroll) {
|
|
100
100
|
const row = rows[scroll];
|
|
101
|
-
if (row === undefined ||
|
|
101
|
+
if (row === undefined || row.kind === "group")
|
|
102
102
|
return undefined;
|
|
103
103
|
const header = headerAbove(rows, scroll);
|
|
104
104
|
const headerRow = header < 0 ? undefined : rows[header];
|
|
105
105
|
return headerRow !== undefined && headerRow.kind === "group" ? headerRow.title : undefined;
|
|
106
106
|
}
|
|
107
107
|
/** One blank row above the first group while the list is scrolled to the top. */
|
|
108
|
-
export function topPaddingRows(scroll) {
|
|
109
|
-
return scroll <= 0 ? 1 : 0;
|
|
108
|
+
export function topPaddingRows(scroll, enabled = true) {
|
|
109
|
+
return enabled && scroll <= 0 ? 1 : 0;
|
|
110
110
|
}
|
|
111
111
|
/** Rows of content visible after the padding and any pinned header. */
|
|
112
|
-
export function visibleRowCount(rows, bodyHeight, scroll) {
|
|
113
|
-
const reserved = topPaddingRows(scroll) + (stickyHeaderFor(rows, scroll) === undefined ? 0 : 1);
|
|
112
|
+
export function visibleRowCount(rows, bodyHeight, scroll, options = {}) {
|
|
113
|
+
const reserved = topPaddingRows(scroll, options.topPadding !== false) + (stickyHeaderFor(rows, scroll) === undefined ? 0 : 1);
|
|
114
114
|
return Math.max(1, bodyHeight - reserved);
|
|
115
115
|
}
|
|
116
|
-
export function maxScrollFor(rows, bodyHeight) {
|
|
116
|
+
export function maxScrollFor(rows, bodyHeight, options = {}) {
|
|
117
117
|
let scroll = Math.max(0, rows.length - 1);
|
|
118
118
|
for (let pass = 0; pass < 8; pass++) {
|
|
119
|
-
const next = Math.max(0, rows.length - visibleRowCount(rows, bodyHeight, scroll));
|
|
119
|
+
const next = Math.max(0, rows.length - visibleRowCount(rows, bodyHeight, scroll, options));
|
|
120
120
|
if (next === scroll)
|
|
121
121
|
break;
|
|
122
122
|
scroll = next;
|
|
123
123
|
}
|
|
124
124
|
return scroll;
|
|
125
125
|
}
|
|
126
|
-
export function clampScroll(rows, bodyHeight, scroll) {
|
|
127
|
-
const bounded = Math.min(Math.max(scroll, 0), maxScrollFor(rows, bodyHeight));
|
|
128
|
-
return { scroll: bounded, visible: visibleRowCount(rows, bodyHeight, bounded) };
|
|
126
|
+
export function clampScroll(rows, bodyHeight, scroll, options = {}) {
|
|
127
|
+
const bounded = Math.min(Math.max(scroll, 0), maxScrollFor(rows, bodyHeight, options));
|
|
128
|
+
return { scroll: bounded, visible: visibleRowCount(rows, bodyHeight, bounded, options) };
|
|
129
129
|
}
|
|
130
130
|
/**
|
|
131
131
|
* Scroll that brings the selection into view, moving the least it can. A reveal
|
|
@@ -158,14 +158,27 @@ export function scrollForSelection(rows, bodyHeight, scroll, selected, reveal) {
|
|
|
158
158
|
return next;
|
|
159
159
|
}
|
|
160
160
|
/** Everything a renderer needs for one frame, derived rather than remembered. */
|
|
161
|
-
export function layoutList(rows, bodyHeight, scroll) {
|
|
162
|
-
const clamped = clampScroll(rows, bodyHeight, scroll);
|
|
161
|
+
export function layoutList(rows, bodyHeight, scroll, options = {}) {
|
|
162
|
+
const clamped = clampScroll(rows, bodyHeight, scroll, options);
|
|
163
163
|
const sticky = stickyHeaderFor(rows, clamped.scroll);
|
|
164
|
-
const padding = topPaddingRows(clamped.scroll);
|
|
164
|
+
const padding = topPaddingRows(clamped.scroll, options.topPadding !== false);
|
|
165
165
|
const indexes = [];
|
|
166
|
-
|
|
166
|
+
// Invariant: a spacer at the scroll boundary belongs to the outgoing pinned section.
|
|
167
|
+
// The pin represents that transition, so the spacer spends no body row and the final
|
|
168
|
+
// setting remains reachable at the bottom.
|
|
169
|
+
const firstOffset = rows[clamped.scroll]?.kind === "spacer" && sticky !== undefined ? 1 : 0;
|
|
170
|
+
for (let offset = firstOffset; indexes.length < clamped.visible && clamped.scroll + offset < rows.length; offset++) {
|
|
167
171
|
indexes.push(clamped.scroll + offset);
|
|
168
172
|
}
|
|
173
|
+
// Invariant: a bottom clamp can land on the outgoing spacer with too few rows after it to fill the
|
|
174
|
+
// viewport. The pinned heading already represents that boundary, so fill the freed capacity
|
|
175
|
+
// from the same section rather than exposing a synthetic blank row at the bottom.
|
|
176
|
+
if (firstOffset > 0 && indexes.length < clamped.visible) {
|
|
177
|
+
const header = headerAbove(rows, clamped.scroll);
|
|
178
|
+
for (let index = clamped.scroll - 1; index > header && indexes.length < clamped.visible; index--) {
|
|
179
|
+
indexes.unshift(index);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
169
182
|
return {
|
|
170
183
|
scroll: clamped.scroll,
|
|
171
184
|
visible: clamped.visible,
|
|
@@ -41,7 +41,7 @@ export interface ListRowPlacement {
|
|
|
41
41
|
* a number does not shift its own value out of the column it shares.
|
|
42
42
|
*/
|
|
43
43
|
export declare function valueColumnFor(rows: readonly ListViewRow[], indent?: number, gap?: number): number;
|
|
44
|
-
/** A group's name
|
|
44
|
+
/** A group's name with the shared one-cell section inset used by owned screens. */
|
|
45
45
|
export declare function renderGroupHeader(title: string, width: number, theme: UiTheme): string;
|
|
46
46
|
/**
|
|
47
47
|
* One row, painted. The label carries the selection, the value carries the
|
|
@@ -11,9 +11,11 @@ export function valueColumnFor(rows, indent = 2, gap = 2) {
|
|
|
11
11
|
const stepper = rows.some(row => row.stepper !== undefined) ? STEPPER_RESERVE : 0;
|
|
12
12
|
return indent + widest + gap + stepper;
|
|
13
13
|
}
|
|
14
|
-
/** A group's name
|
|
14
|
+
/** A group's name with the shared one-cell section inset used by owned screens. */
|
|
15
15
|
export function renderGroupHeader(title, width, theme) {
|
|
16
|
-
|
|
16
|
+
if (width <= 0)
|
|
17
|
+
return "";
|
|
18
|
+
return ` ${truncateToWidth(theme.fg("mdHeading", theme.bold(title)), width - 1)}`;
|
|
17
19
|
}
|
|
18
20
|
/**
|
|
19
21
|
* One row, painted. The label carries the selection, the value carries the
|
|
@@ -45,8 +45,8 @@ export function routeMouseInput(data, claim) {
|
|
|
45
45
|
for (let match = pattern.exec(data); match !== null; match = pattern.exec(data)) {
|
|
46
46
|
output += data.slice(index, match.index);
|
|
47
47
|
index = match.index + match[0].length;
|
|
48
|
-
const event = toEvent(Number
|
|
49
|
-
if (event
|
|
48
|
+
const event = toEvent(Number(match[1]), Number(match[2]), Number(match[3]), match[4] === "m");
|
|
49
|
+
if (event === null || claim(event, match[0]))
|
|
50
50
|
consumed = true;
|
|
51
51
|
else
|
|
52
52
|
output += match[0];
|
|
@@ -55,6 +55,8 @@ export function routeMouseInput(data, claim) {
|
|
|
55
55
|
return { data: output, consumed };
|
|
56
56
|
}
|
|
57
57
|
function toEvent(code, column, row, released) {
|
|
58
|
+
if ((code & 66) === 66)
|
|
59
|
+
return null;
|
|
58
60
|
if ((code & 64) !== 0) {
|
|
59
61
|
const kind = (code & 1) === 0 ? "wheel-up" : "wheel-down";
|
|
60
62
|
return { kind, button: 0, column, row };
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* Colour as a port, so a screen can be rendered and asserted without a terminal
|
|
3
|
-
* or a theme, and so the component layer never imports a Pi adapter.
|
|
4
|
-
*/
|
|
5
|
-
export type UiThemeToken = "accent" | "text" | "muted" | "dim" | "border" | "error";
|
|
1
|
+
export type UiThemeToken = "accent" | "mdHeading" | "text" | "muted" | "dim" | "border" | "error";
|
|
6
2
|
export interface UiTheme {
|
|
7
3
|
fg(token: UiThemeToken, text: string): string;
|
|
8
4
|
bold(text: string): string;
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Colour as a port, so a screen can be rendered and asserted without a terminal
|
|
3
|
-
* or a theme, and so the component layer never imports a Pi adapter.
|
|
4
|
-
*/
|
|
5
1
|
/** Renders every token as plain text. What tests assert against. */
|
|
6
2
|
export const PLAIN_THEME = Object.freeze({
|
|
7
3
|
fg: (_token, text) => text,
|
|
@@ -26,7 +26,9 @@ export interface ValueMenuFrame {
|
|
|
26
26
|
readonly rows: number;
|
|
27
27
|
}
|
|
28
28
|
export interface ValueMenuLayout {
|
|
29
|
-
/**
|
|
29
|
+
/** First screen row available to the menu. Defaults to zero. */
|
|
30
|
+
readonly bodyTop?: number;
|
|
31
|
+
/** Rows available between the fixed header and footer. */
|
|
30
32
|
readonly bodyHeight: number;
|
|
31
33
|
/** Full surface width, so the menu stays inside it. */
|
|
32
34
|
readonly surfaceWidth: number;
|
|
@@ -2,10 +2,12 @@ import { overlaySpan } from "./spans.js";
|
|
|
2
2
|
import { displayWidth, padToWidth } from "./text.js";
|
|
3
3
|
/** Where the menu is placed: below its anchor where there is room, else above. */
|
|
4
4
|
export function valueMenuFrame(state, anchor, layout) {
|
|
5
|
+
const bodyTop = layout.bodyTop ?? 0;
|
|
6
|
+
const bodyBottom = bodyTop + layout.bodyHeight;
|
|
5
7
|
const below = anchor.screenRow + 1;
|
|
6
|
-
const top = below + state.choices.length <=
|
|
8
|
+
const top = below + state.choices.length <= bodyBottom
|
|
7
9
|
? below
|
|
8
|
-
: Math.max(
|
|
10
|
+
: Math.max(bodyTop, anchor.screenRow - state.choices.length);
|
|
9
11
|
const width = Math.max(...state.choices.map(choice => displayWidth(choice) + 4), 6);
|
|
10
12
|
const column = Math.min(anchor.valueColumn, Math.max(0, layout.surfaceWidth - width - layout.reservedRight));
|
|
11
13
|
return { top, column, width, rows: state.choices.length };
|
|
@@ -17,9 +19,15 @@ export function renderValueMenu(lines, state, frame, theme) {
|
|
|
17
19
|
const target = frame.top + index;
|
|
18
20
|
if (target < 0 || target >= output.length)
|
|
19
21
|
return;
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
const
|
|
22
|
+
const active = index === state.index;
|
|
23
|
+
const paint = active ? theme.highlight : theme.panel;
|
|
24
|
+
const current = choice === state.current;
|
|
25
|
+
const tail = padToWidth(`${current ? " " : " "}${choice} `, frame.width - (current ? 1 : 0));
|
|
26
|
+
// Invariant: the effective-value check uses the same accent as modal marks, while
|
|
27
|
+
// the rest of an active row keeps its highlighted foreground and background.
|
|
28
|
+
const painted = current
|
|
29
|
+
? `${paint(theme.fg("accent", "✓"))}${paint(tail)}`
|
|
30
|
+
: paint(tail);
|
|
23
31
|
output[target] = overlaySpan(output[target] ?? "", frame.column, frame.column + frame.width, painted);
|
|
24
32
|
});
|
|
25
33
|
return output;
|
|
@@ -58,7 +58,7 @@ node scripts/governance/local-worktree-cleanup.mjs complete \
|
|
|
58
58
|
|
|
59
59
|
`complete` is explicit cleanup authorization for that exact candidate. It creates and releases an exact registration when needed, applies the repository-owned generated-path policy, verifies live merge/archive/CI/ref evidence, evaluates only that candidate, uses journaled non-force Git removal, deletes only the unchanged local topic ref, and leaves persistent watcher authority unchanged. Repeating it reports the completed candidate as already absent. Existing conflicting ownership, identity drift, unavailable evidence, or unknown content remains blocking.
|
|
60
60
|
|
|
61
|
-
The central disposable policy is `node_modules`, `dist`, `.builds`, `.artifacts`, `native/process-guardian/target`,
|
|
61
|
+
The central disposable policy is `node_modules`, `dist`, `.builds`, `.artifacts`, `native/process-guardian/target`, `native/terminal-host/target`, and the exact generated file `src/integrations/pi/engine/pi-settings-metadata.json`. The `.artifacts` root is the repository's ignored generated-artifact root (finalization and validation reports, packed candidates, agent-written logs and diffs); the two native roots contain repository-generated Cargo output; Vitest writes the metadata file for source-side settings tests and leaves it shared for overlapping test processes until worktree cleanup. Registrations that still name `.artifacts/openspec-archive` or `.artifacts/validation` stay valid and are widened to the current policy on the next `complete`. Each encountered path must be ignored and stay inside the exact worktree with no link, special file, or nested repository boundary. Authority is component-exact: near matches such as `.artifacts-user`, `artifacts`, or `pi-settings-metadata-user.json`, arbitrary `target` directories, and sibling native projects remain blocking. Tracked/staged/unstaged/untracked content and every unknown ignored path still block. A tracked regular `.gitmodules` file alone is ordinary content; actual nested `.git` metadata, gitlinks, configured submodules, and submodule changes block. Ordinary content and these approved generated paths are traversed under separate finite entry allowances, so a normal dependency installation does not consume the ordinary source-tree allowance; both allowances retain the same deadline and content-boundary checks. Once those checks pass, cleanup deletes the declared disposable roots or files itself with a bounded retry for transient Windows sharing violations before handing the worktree to Git, so non-force Git removal only has to delete tracked content. A disposable path that stays locked after the retry budget reports `blocked` with `disposable-path-locked` and the path; the worktree, its `.git` pointer, and its journal are untouched, so stop the process holding the handle and rerun the same command.
|
|
62
62
|
|
|
63
63
|
Agents do not manually remove generated content, call `git worktree remove`, or delete the local branch after delivery. The JSON result is authoritative: report success only for `removed` or verified `already-absent`; otherwise retain the worktree and report the exact blocker. A handed-off entry whose worktree was deleted by hand completes through its journal, and its branch is deleted under the accepted-ancestry rule. Legacy roles can supply separate `--source-pr`, `--candidate-pr`, and `--role` values.
|
|
64
64
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@timurproko/a1",
|
|
3
|
-
"version": "0.1.8-dev.
|
|
3
|
+
"version": "0.1.8-dev.536",
|
|
4
4
|
"description": "Standalone terminal workspace for supervised native and managed agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"privateLaunchContract": "neutral-launch-v1",
|
|
@@ -64,8 +64,8 @@
|
|
|
64
64
|
"typecheck:bin": "tsgo -p tsconfig.bin.json"
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
|
-
"@earendil-works/pi-coding-agent": "0.
|
|
68
|
-
"@earendil-works/pi-tui": "0.
|
|
67
|
+
"@earendil-works/pi-coding-agent": "0.87.0",
|
|
68
|
+
"@earendil-works/pi-tui": "0.87.0",
|
|
69
69
|
"@silvia-odwyer/photon-node": "0.3.4",
|
|
70
70
|
"chalk": "5.6.2",
|
|
71
71
|
"cross-spawn": "7.0.6",
|