@timurproko/a1 0.2.7-dev.1252 → 0.2.7-dev.1255

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 (253) hide show
  1. package/bin/ui.js +3 -3
  2. package/dist/app/session-shell/clipboard-diagnostics.d.ts +2 -2
  3. package/dist/app/session-shell/clipboard-image.d.ts +0 -1
  4. package/dist/app/session-shell/clipboard-image.js +1 -1
  5. package/dist/app/session-shell/dialog-coordinator.d.ts +6 -5
  6. package/dist/app/session-shell/dialog-coordinator.js +3 -4
  7. package/dist/app/session-shell/dock-chrome.d.ts +11 -6
  8. package/dist/app/session-shell/dock-chrome.js +5 -8
  9. package/dist/app/session-shell/editor-hyperlink-budget.d.ts +0 -2
  10. package/dist/app/session-shell/editor-hyperlink-budget.js +1 -1
  11. package/dist/app/session-shell/exit-notice.d.ts +2 -2
  12. package/dist/app/session-shell/exit-notice.js +1 -1
  13. package/dist/app/session-shell/extension-surface.d.ts +8 -7
  14. package/dist/app/session-shell/helper-pool.d.ts +3 -4
  15. package/dist/app/session-shell/helper-pool.js +1 -1
  16. package/dist/app/session-shell/image-preparation-client.d.ts +4 -3
  17. package/dist/app/session-shell/image-preparation.d.ts +0 -2
  18. package/dist/app/session-shell/image-preparation.js +2 -2
  19. package/dist/app/session-shell/image-source.d.ts +2 -3
  20. package/dist/app/session-shell/image-source.js +2 -2
  21. package/dist/app/session-shell/input-surface-switch.d.ts +9 -7
  22. package/dist/app/session-shell/input-surface-switch.js +1 -2
  23. package/dist/app/session-shell/login-interaction.d.ts +5 -4
  24. package/dist/app/session-shell/login-interaction.js +2 -3
  25. package/dist/app/session-shell/paste-executor.d.ts +4 -8
  26. package/dist/app/session-shell/paste-executor.js +2 -2
  27. package/dist/app/session-shell/paste-protocol.d.ts +2 -2
  28. package/dist/app/session-shell/path-chip-presentation.d.ts +0 -5
  29. package/dist/app/session-shell/path-chip-presentation.js +3 -3
  30. package/dist/app/session-shell/prompt-chips.d.ts +8 -7
  31. package/dist/app/session-shell/prompt-history-controller.d.ts +3 -3
  32. package/dist/app/session-shell/prompt-submission.d.ts +5 -2
  33. package/dist/app/session-shell/prompt-submission.js +4 -5
  34. package/dist/app/session-shell/quit-outro-effects.d.ts +3 -3
  35. package/dist/app/session-shell/quit-outro-effects.js +1 -4
  36. package/dist/app/session-shell/quit-outro.d.ts +9 -12
  37. package/dist/app/session-shell/quit-outro.js +11 -11
  38. package/dist/app/session-shell/response-copy-protocol.d.ts +3 -2
  39. package/dist/app/session-shell/response-copy-transport.d.ts +2 -14
  40. package/dist/app/session-shell/response-copy-transport.js +1 -1
  41. package/dist/app/session-shell/session-lifecycle.d.ts +2 -1
  42. package/dist/app/session-shell/session-shell-root.d.ts +74 -89
  43. package/dist/app/session-shell/session-shell-root.js +81 -113
  44. package/dist/app/session-shell/session-shell.d.ts +13 -16
  45. package/dist/app/session-shell/session-shell.js +144 -268
  46. package/dist/app/session-shell/session-viewport-controller.d.ts +7 -6
  47. package/dist/app/session-shell/session-viewport-controller.js +2 -2
  48. package/dist/app/session-shell/settings-bindings.d.ts +24 -2
  49. package/dist/app/session-shell/settings-bindings.js +24 -0
  50. package/dist/app/session-shell/share-operation.d.ts +3 -3
  51. package/dist/app/session-shell/share-operation.js +4 -6
  52. package/dist/app/session-shell/shell-clipboard.d.ts +59 -0
  53. package/dist/app/session-shell/shell-clipboard.js +119 -0
  54. package/dist/app/session-shell/shell-editor-factory.d.ts +8 -4
  55. package/dist/app/session-shell/shell-editor-factory.js +13 -15
  56. package/dist/app/session-shell/shell-host.d.ts +16 -17
  57. package/dist/app/session-shell/shell-host.js +18 -19
  58. package/dist/app/session-shell/shell-layout.d.ts +2 -2
  59. package/dist/app/session-shell/shell-prompt-suggestions.d.ts +26 -0
  60. package/dist/app/session-shell/shell-prompt-suggestions.js +48 -0
  61. package/dist/app/session-shell/suggestion-surface.d.ts +1 -6
  62. package/dist/app/session-shell/suggestion-surface.js +1 -1
  63. package/dist/app/session-shell/system-clipboard.d.ts +2 -14
  64. package/dist/app/session-shell/system-clipboard.js +2 -7
  65. package/dist/app/session-shell/transcript-document.d.ts +11 -8
  66. package/dist/app/session-shell/transcript-document.js +13 -14
  67. package/dist/app/session-shell/viewport-layout.d.ts +2 -2
  68. package/dist/app/session-shell/workflow-output.d.ts +5 -3
  69. package/dist/app/session-shell/workflow-output.js +13 -15
  70. package/dist/cli/package-messages.d.ts +0 -1
  71. package/dist/cli/package-messages.js +1 -1
  72. package/dist/cli/session-context.d.ts +1 -1
  73. package/dist/cli/uninstall.d.ts +3 -2
  74. package/dist/composition/owned-settings.d.ts +2 -1
  75. package/dist/composition/owned-settings.js +0 -3
  76. package/dist/composition/owned-ui.d.ts +1 -1
  77. package/dist/composition/owned-ui.js +27 -27
  78. package/dist/composition/reference-selection-options.d.ts +1 -1
  79. package/dist/composition/reference-selection-options.js +1 -1
  80. package/dist/composition/session-runtime-registry.d.ts +2 -1
  81. package/dist/composition/settings-route-host.js +3 -10
  82. package/dist/composition/settings-search-input.d.ts +2 -1
  83. package/dist/composition/startup-route.d.ts +2 -2
  84. package/dist/composition/startup-route.js +2 -2
  85. package/dist/contracts/owned-ui/extension-ui.d.ts +2 -1
  86. package/dist/contracts/owned-ui/index.d.ts +1 -0
  87. package/dist/contracts/owned-ui/session-presenters.d.ts +3 -0
  88. package/dist/contracts/owned-ui/shell-components.d.ts +543 -0
  89. package/dist/contracts/owned-ui/shell-components.js +1 -0
  90. package/dist/contracts/presentation/component.d.ts +17 -0
  91. package/dist/contracts/presentation/component.js +8 -0
  92. package/dist/contracts/presentation/index.d.ts +6 -15
  93. package/dist/contracts/presentation/index.js +2 -0
  94. package/dist/contracts/presentation/terminal.d.ts +290 -0
  95. package/dist/contracts/presentation/terminal.js +1 -0
  96. package/dist/contracts/presentation/theme.d.ts +46 -0
  97. package/dist/contracts/presentation/theme.js +1 -0
  98. package/dist/features/launch/development-launch.js +1 -1
  99. package/dist/features/launch/runtime-selection.d.ts +2 -2
  100. package/dist/features/launch/runtime-selection.js +2 -2
  101. package/dist/features/owned-ui/project-trust-prompt.d.ts +2 -2
  102. package/dist/features/owned-ui/project-trust-prompt.js +1 -1
  103. package/dist/features/owned-ui/release-note-state.d.ts +2 -1
  104. package/dist/features/owned-ui/settings-app.js +38 -219
  105. package/dist/features/owned-ui/settings-edits.d.ts +31 -0
  106. package/dist/features/owned-ui/settings-edits.js +139 -0
  107. package/dist/features/owned-ui/settings-scroll-rail.d.ts +29 -0
  108. package/dist/features/owned-ui/settings-scroll-rail.js +79 -0
  109. package/dist/features/owned-ui/settings-search-input.d.ts +2 -1
  110. package/dist/features/prompt-history/service.d.ts +3 -2
  111. package/dist/foundation/lifecycle/claim-gate.d.ts +2 -1
  112. package/dist/foundation/release/automatic-update.d.ts +5 -14
  113. package/dist/foundation/release/automatic-update.js +14 -14
  114. package/dist/foundation/release/bootstrap.js +4 -4
  115. package/dist/foundation/release/dependency-certification.d.ts +0 -1
  116. package/dist/foundation/release/dependency-certification.js +1 -1
  117. package/dist/foundation/release/early-accent.d.ts +2 -2
  118. package/dist/foundation/release/early-accent.js +1 -1
  119. package/dist/foundation/release/index.d.ts +2 -2
  120. package/dist/foundation/release/index.js +1 -1
  121. package/dist/foundation/release/latest-release.d.ts +3 -18
  122. package/dist/foundation/release/latest-release.js +10 -10
  123. package/dist/foundation/release/ordinary-launch-selection.d.ts +1 -1
  124. package/dist/foundation/release/ordinary-launch-selection.js +1 -1
  125. package/dist/foundation/release/release-gc.d.ts +3 -3
  126. package/dist/foundation/release/release-gc.js +4 -4
  127. package/dist/foundation/release/{cohort-state.d.ts → release-state.d.ts} +23 -23
  128. package/dist/foundation/release/{cohort-state.js → release-state.js} +8 -8
  129. package/dist/foundation/release/update-activation.js +2 -2
  130. package/dist/foundation/release/update-execution-lease.d.ts +2 -3
  131. package/dist/foundation/release/update-execution-lease.js +1 -1
  132. package/dist/foundation/release/update-launch.d.ts +2 -2
  133. package/dist/foundation/release/update.d.ts +0 -2
  134. package/dist/foundation/release/update.js +14 -14
  135. package/dist/foundation/startup/startup-budget.d.ts +5 -5
  136. package/dist/foundation/startup/startup-budget.js +2 -2
  137. package/dist/integrations/pi/components/editor-interaction.d.ts +4 -12
  138. package/dist/integrations/pi/components/index.d.ts +15 -9
  139. package/dist/integrations/pi/components/index.js +9 -5
  140. package/dist/integrations/pi/components/lazy-selectors.d.ts +2 -10
  141. package/dist/integrations/pi/components/lazy-selectors.js +1 -1
  142. package/dist/integrations/pi/components/modal-frame.d.ts +5 -22
  143. package/dist/integrations/pi/components/modal-frame.js +3 -23
  144. package/dist/integrations/pi/components/owned-editor-ux.d.ts +4 -3
  145. package/dist/integrations/pi/components/prompt-input-port.d.ts +2 -19
  146. package/dist/integrations/pi/components/resources/builtin-themes.d.ts +2 -1
  147. package/dist/integrations/pi/components/shell-editor-autocomplete.d.ts +3 -2
  148. package/dist/integrations/pi/components/shell-footer-status.d.ts +2 -2
  149. package/dist/integrations/pi/components/shell-footer-status.js +3 -2
  150. package/dist/integrations/pi/components/shell-presenters-info.d.ts +6 -5
  151. package/dist/integrations/pi/components/shell-presenters-info.js +2 -1
  152. package/dist/integrations/pi/components/shell-session-info-reference.d.ts +2 -1
  153. package/dist/integrations/pi/components/shell-shared-facade.d.ts +33 -227
  154. package/dist/integrations/pi/components/shell-shared-facade.js +8 -1
  155. package/dist/integrations/pi/components/skills-command.d.ts +1 -9
  156. package/dist/integrations/pi/components/skills-command.js +5 -5
  157. package/dist/integrations/pi/components/theme.d.ts +9 -2
  158. package/dist/integrations/pi/components/theme.js +17 -2
  159. package/dist/integrations/pi/components/thinking-selector-dialog.d.ts +2 -1
  160. package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.d.ts +2 -2
  161. package/dist/integrations/pi/engine/adapter.d.ts +3 -5
  162. package/dist/integrations/pi/engine/adapter.js +3 -12
  163. package/dist/integrations/pi/engine/changelog.d.ts +2 -2
  164. package/dist/integrations/pi/engine/changelog.js +3 -3
  165. package/dist/integrations/pi/engine/compaction-progress.d.ts +2 -3
  166. package/dist/integrations/pi/engine/compaction-progress.js +1 -1
  167. package/dist/integrations/pi/engine/conformance.d.ts +2 -1
  168. package/dist/integrations/pi/engine/default-model-setting.d.ts +0 -2
  169. package/dist/integrations/pi/engine/default-model-setting.js +1 -2
  170. package/dist/integrations/pi/engine/event-delivery.d.ts +2 -1
  171. package/dist/integrations/pi/engine/extension-ui-binding.d.ts +2 -1
  172. package/dist/integrations/pi/engine/host.js +2 -2
  173. package/dist/integrations/pi/engine/message-values.d.ts +0 -1
  174. package/dist/integrations/pi/engine/message-values.js +1 -1
  175. package/dist/integrations/pi/engine/pending-delivery.d.ts +0 -4
  176. package/dist/integrations/pi/engine/pending-delivery.js +3 -3
  177. package/dist/integrations/pi/engine/ports.d.ts +7 -1
  178. package/dist/integrations/pi/engine/ports.js +4 -0
  179. package/dist/integrations/pi/engine/project-trust-preflight.d.ts +2 -1
  180. package/dist/integrations/pi/engine/prompt-suggestions.d.ts +3 -2
  181. package/dist/integrations/pi/engine/provider-authentication.d.ts +1 -1
  182. package/dist/integrations/pi/engine/public-main-entry.d.ts +1 -5
  183. package/dist/integrations/pi/engine/public-main-entry.js +1 -1
  184. package/dist/integrations/pi/engine/repository-pr-rest.d.ts +1 -9
  185. package/dist/integrations/pi/engine/repository-pr-rest.js +2 -2
  186. package/dist/integrations/pi/engine/repository-pr.d.ts +1 -3
  187. package/dist/integrations/pi/engine/repository-pr.js +1 -1
  188. package/dist/integrations/pi/engine/resource-catalog.d.ts +2 -1
  189. package/dist/integrations/pi/engine/session-integration.d.ts +1 -1
  190. package/dist/integrations/pi/engine/session-runtime.d.ts +4 -3
  191. package/dist/integrations/pi/engine/settings-bridge.d.ts +0 -2
  192. package/dist/integrations/pi/engine/settings-bridge.js +1 -1
  193. package/dist/integrations/pi/engine/settings-port.d.ts +3 -2
  194. package/dist/integrations/pi/engine/transcript-projection.d.ts +2 -1
  195. package/dist/integrations/pi/engine/workflow-contexts.d.ts +1 -1
  196. package/dist/integrations/pi/engine/workflow-runner.d.ts +1 -1
  197. package/dist/integrations/pi/engine/workflow-support.d.ts +0 -6
  198. package/dist/integrations/pi/engine/workflow-support.js +4 -18
  199. package/dist/integrations/pi/engine/workflows.d.ts +5 -5
  200. package/dist/integrations/pi/session-presenters/components.d.ts +3 -0
  201. package/dist/integrations/pi/session-presenters/components.js +75 -0
  202. package/dist/integrations/pi/session-presenters/index.d.ts +1 -0
  203. package/dist/integrations/pi/session-presenters/index.js +1 -0
  204. package/dist/integrations/pi/session-presenters/presentation.d.ts +3 -0
  205. package/dist/integrations/pi/session-presenters/presentation.js +10 -0
  206. package/dist/integrations/pi/session-presenters/presenters.d.ts +2 -1
  207. package/dist/integrations/pi/session-presenters/presenters.js +3 -1
  208. package/dist/integrations/pi/tui-runtime/adapter.js +21 -30
  209. package/dist/integrations/pi/tui-runtime/contracts.d.ts +22 -166
  210. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +5 -40
  211. package/dist/integrations/pi/tui-runtime/index.d.ts +1 -0
  212. package/dist/integrations/pi/tui-runtime/index.js +1 -0
  213. package/dist/integrations/pi/tui-runtime/input-presentation-coordinator.d.ts +4 -6
  214. package/dist/integrations/pi/tui-runtime/overlay-geometry.d.ts +2 -8
  215. package/dist/integrations/pi/tui-runtime/overlay-geometry.js +3 -9
  216. package/dist/integrations/pi/tui-runtime/runtime-factory.d.ts +3 -0
  217. package/dist/integrations/pi/tui-runtime/runtime-factory.js +11 -0
  218. package/dist/ui/components/index.d.ts +2 -2
  219. package/dist/ui/components/index.js +1 -1
  220. package/dist/ui/components/selection-copy.d.ts +0 -1
  221. package/dist/ui/components/selection-copy.js +0 -12
  222. package/dist/ui/components/theme.d.ts +4 -19
  223. package/dist/ui/components/theme.js +6 -0
  224. package/dist/ui/settings/declarations.d.ts +2 -3
  225. package/dist/ui/settings/declarations.js +2 -3
  226. package/dist/ui/settings/early-accent.js +1 -1
  227. package/dist/ui/settings/index.d.ts +3 -5
  228. package/dist/ui/settings/index.js +2 -3
  229. package/dist/ui/settings/manager.d.ts +0 -4
  230. package/dist/ui/settings/manager.js +6 -62
  231. package/dist/ui/settings/resolution.d.ts +6 -18
  232. package/dist/ui/settings/resolution.js +4 -103
  233. package/dist/ui/settings/sections.d.ts +0 -4
  234. package/dist/ui/settings/sections.js +1 -1
  235. package/docs/architecture/boundaries.md +2 -2
  236. package/docs/architecture/internal-naming.md +2 -0
  237. package/docs/architecture/project-structure.md +4 -2
  238. package/docs/validation.md +1 -1
  239. package/package.json +3 -4
  240. package/dist/integrations/pi/components/components.d.ts +0 -4
  241. package/dist/integrations/pi/components/components.js +0 -48
  242. package/dist/integrations/pi/components/conformance.d.ts +0 -18
  243. package/dist/integrations/pi/components/conformance.js +0 -70
  244. package/dist/integrations/pi/components/shell-components.d.ts +0 -7
  245. package/dist/integrations/pi/components/shell-components.js +0 -7
  246. package/dist/integrations/pi/components/upstream/theme/theme-controller.d.ts +0 -33
  247. package/dist/integrations/pi/components/upstream/theme/theme-controller.js +0 -114
  248. package/dist/ui/settings/migrations.d.ts +0 -19
  249. package/dist/ui/settings/migrations.js +0 -225
  250. package/dist/ui/settings/progress-palette.generated.d.ts +0 -139
  251. package/dist/ui/settings/progress-palette.generated.js +0 -139
  252. /package/dist/{foundation/release → contracts/presentation}/progress-palette.generated.d.ts +0 -0
  253. /package/dist/{foundation/release → contracts/presentation}/progress-palette.generated.js +0 -0
@@ -1,21 +1,6 @@
1
- export type UiThemeToken = "accent" | "mdHeading" | "text" | "muted" | "dim" | "border" | "error" | "success";
2
- export interface UiTheme {
3
- fg(token: UiThemeToken, text: string): string;
4
- bold(text: string): string;
5
- /**
6
- * The terminal's own foreground, left unpainted. What a list's own text is:
7
- * a theme built for a light background would otherwise write near-black rows
8
- * into a dark terminal, which is how the engine leaves its lists too.
9
- */
10
- plain(text: string): string;
11
- /** Optional palette preview used by controls that choose the active accent. */
12
- accentPreview?(color: string, text: string): string | null;
13
- /** Selection background for an active list item or floating-surface row. */
14
- highlight(text: string): string;
15
- /** A control that is present but cannot act: quieter than quiet text. */
16
- disabled(text: string): string;
17
- /** Background for a floating surface, so it reads as above the content. */
18
- panel(text: string): string;
19
- }
1
+ import type { ThemeSource, UiTheme, UiThemeBackground, UiThemeToken } from "../../contracts/presentation/index.js";
2
+ export type { ThemeSource, UiTheme, UiThemeBackground, UiThemeToken };
20
3
  /** Renders every token as plain text. What tests assert against. */
21
4
  export declare const PLAIN_THEME: UiTheme;
5
+ /** A theme source that never changes and paints nothing. */
6
+ export declare const PLAIN_THEME_SOURCE: ThemeSource;
@@ -6,4 +6,10 @@ export const PLAIN_THEME = Object.freeze({
6
6
  highlight: (text) => text,
7
7
  disabled: (text) => text,
8
8
  panel: (text) => text,
9
+ background: (_token, text) => text,
10
+ });
11
+ /** A theme source that never changes and paints nothing. */
12
+ export const PLAIN_THEME_SOURCE = Object.freeze({
13
+ current: () => PLAIN_THEME,
14
+ onChange: () => () => { },
9
15
  });
@@ -1,4 +1,3 @@
1
- export declare const OWNED_UI_SETTINGS_VERSION = 21;
2
1
  export type OwnedUiSettingValue = string | number | boolean;
3
2
  export type OwnedUiSettingApplication = "live" | "restart";
4
3
  export interface OwnedUiSettingDeclaration {
@@ -30,10 +29,10 @@ export declare const OWNED_SETTING_DECLARATIONS: Readonly<{
30
29
  id: "generic";
31
30
  title: "Generic";
32
31
  }>;
33
- description: "Auto checks the running channel every 15 minutes while open and installs verified updates silently, then shows Update installed, restart to update; the next start runs it. No leaves updates manual. Applies on next start.";
32
+ description: "Auto checks the running channel every 15 minutes while open and installs verified updates silently, then shows Update installed, restart to update; the next start runs it. Manual leaves updating to you (a1 update). Applies on next start.";
34
33
  application: "restart";
35
34
  defaultValue: "auto";
36
- allowedValues: readonly ["auto", "no"];
35
+ allowedValues: readonly ["auto", "manual"];
37
36
  }>;
38
37
  readonly accentColor: Readonly<{
39
38
  id: "accentColor";
@@ -1,4 +1,3 @@
1
- export const OWNED_UI_SETTINGS_VERSION = 21;
2
1
  const UI_ACCENT_COLOR_CHOICES = Object.freeze([
3
2
  "blue", "purple", "cyan", "green", "orange", "pink",
4
3
  ]);
@@ -13,10 +12,10 @@ export const OWNED_SETTING_DECLARATIONS = Object.freeze({
13
12
  id: "updateCheck",
14
13
  label: "Update",
15
14
  section: GENERIC_SECTION,
16
- description: "Auto checks the running channel every 15 minutes while open and installs verified updates silently, then shows Update installed, restart to update; the next start runs it. No leaves updates manual. Applies on next start.",
15
+ description: "Auto checks the running channel every 15 minutes while open and installs verified updates silently, then shows Update installed, restart to update; the next start runs it. Manual leaves updating to you (a1 update). Applies on next start.",
17
16
  application: "restart",
18
17
  defaultValue: "auto",
19
- allowedValues: Object.freeze(["auto", "no"]),
18
+ allowedValues: Object.freeze(["auto", "manual"]),
20
19
  }),
21
20
  accentColor: Object.freeze({
22
21
  id: "accentColor",
@@ -2,7 +2,7 @@ import { readFileSync, statSync } from "node:fs";
2
2
  import { homedir } from "node:os";
3
3
  import { isAbsolute, join } from "node:path";
4
4
  import { PRODUCT_IDENTITY } from "../../product-identity.js";
5
- import { SHARED_PROGRESS_PALETTE } from "./progress-palette.generated.js";
5
+ import { SHARED_PROGRESS_PALETTE } from "../../contracts/presentation/index.js";
6
6
  /** Global settings only: project resources must remain unavailable until trust is resolved. */
7
7
  export function readPreTrustAccent(environment = process.env) {
8
8
  try {
@@ -1,9 +1,7 @@
1
- export { OWNED_SETTING_DECLARATIONS, OWNED_UI_SETTINGS_VERSION, OWNED_UI_SETTING_DECLARATIONS, assertOwnedUiSettingDeclarations, findOwnedUiSettingDeclaration, isOwnedSettingId, } from "./declarations.js";
1
+ export { OWNED_SETTING_DECLARATIONS, OWNED_UI_SETTING_DECLARATIONS, assertOwnedUiSettingDeclarations, findOwnedUiSettingDeclaration, isOwnedSettingId, } from "./declarations.js";
2
2
  export type { OwnedSettingId, OwnedSettingValueOf, OwnedUiSettingApplication, OwnedUiSettingDeclaration, OwnedUiSettingValue } from "./declarations.js";
3
- export { OWNED_UI_SETTINGS_MIGRATIONS, assertOwnedUiSettingsMigrations, migrationsFrom, normalizeOwnedUiSettingsValues, } from "./migrations.js";
4
- export type { OwnedUiSettingsCompatibilityResult, OwnedUiSettingsMigration } from "./migrations.js";
5
- export { documentFrom, parseOwnedUiSettingsDocument, resolveOwnedUiSettings, settingValue } from "./resolution.js";
6
- export type { OwnedUiResolvedSetting, OwnedUiSettingSource, OwnedUiSettingsDocument, OwnedUiSettingsNotice, OwnedUiSettingsNoticeCode, OwnedUiSettingsResolution, ResolveOwnedUiSettingsInput, } from "./resolution.js";
3
+ export { resolveOwnedUiSettings, settingValue } from "./resolution.js";
4
+ export type { OwnedUiResolvedSetting, OwnedUiSettingSource, OwnedUiSettingsNotice, OwnedUiSettingsNoticeCode, OwnedUiSettingsResolution, ResolveOwnedUiSettingsInput, } from "./resolution.js";
7
5
  export { AGENT_SECTION_ID, buildOwnedUiSettingsSections, findOwnedUiSettingsEntry } from "./sections.js";
8
6
  export type { AgentSettingsSnapshot, BuildOwnedUiSettingsSectionsInput, OwnedUiSettingsBackend, OwnedUiSettingsEntry, OwnedUiSettingsSection, } from "./sections.js";
9
7
  export { OwnedSettingsManager } from "./manager.js";
@@ -1,6 +1,5 @@
1
- export { OWNED_SETTING_DECLARATIONS, OWNED_UI_SETTINGS_VERSION, OWNED_UI_SETTING_DECLARATIONS, assertOwnedUiSettingDeclarations, findOwnedUiSettingDeclaration, isOwnedSettingId, } from "./declarations.js";
2
- export { OWNED_UI_SETTINGS_MIGRATIONS, assertOwnedUiSettingsMigrations, migrationsFrom, normalizeOwnedUiSettingsValues, } from "./migrations.js";
3
- export { documentFrom, parseOwnedUiSettingsDocument, resolveOwnedUiSettings, settingValue } from "./resolution.js";
1
+ export { OWNED_SETTING_DECLARATIONS, OWNED_UI_SETTING_DECLARATIONS, assertOwnedUiSettingDeclarations, findOwnedUiSettingDeclaration, isOwnedSettingId, } from "./declarations.js";
2
+ export { resolveOwnedUiSettings, settingValue } from "./resolution.js";
4
3
  export { AGENT_SECTION_ID, buildOwnedUiSettingsSections, findOwnedUiSettingsEntry } from "./sections.js";
5
4
  export { OwnedSettingsManager } from "./manager.js";
6
5
  export { assertProfileSettingsNamespaceAvailable, readProfileSettingsNamespace, repairProfileSettingsDocument, updateProfileSettingsNamespace, } from "./profile-document.js";
@@ -1,6 +1,5 @@
1
1
  import type { AgentJsonValue, AgentSettingApplicationBoundary, AgentSettingsPort } from "../../contracts/agent-engine/index.js";
2
2
  import { type OwnedSettingId, type OwnedSettingValueOf, type OwnedUiSettingDeclaration, type OwnedUiSettingValue } from "./declarations.js";
3
- import { type OwnedUiSettingsMigration } from "./migrations.js";
4
3
  import { type OwnedUiSettingsResolution } from "./resolution.js";
5
4
  import { type OwnedUiSettingsBackend, type OwnedUiSettingsSection } from "./sections.js";
6
5
  export interface OwnedSettingsManagerOptions {
@@ -11,10 +10,7 @@ export interface OwnedSettingsManagerOptions {
11
10
  readonly profileId: string;
12
11
  /** Product namespace; defaults to profileId for generic and hermetic consumers. */
13
12
  readonly namespace?: string;
14
- /** Former product configuration root, consulted only while the namespace is absent. */
15
- readonly legacyConfigDir?: string;
16
13
  readonly declarations?: readonly OwnedUiSettingDeclaration[];
17
- readonly migrations?: readonly OwnedUiSettingsMigration[];
18
14
  readonly agent?: AgentSettingsPort | null;
19
15
  readonly agentProvider?: () => AgentSettingsPort | null;
20
16
  readonly hiddenOwnedSettingIds?: readonly string[];
@@ -1,9 +1,7 @@
1
- import { readFileSync } from "node:fs";
2
1
  import path from "node:path";
3
2
  import { assertAgentSettingDescriptor } from "../../contracts/agent-engine/index.js";
4
- import { OWNED_SETTING_DECLARATIONS, OWNED_UI_SETTINGS_VERSION, OWNED_UI_SETTING_DECLARATIONS, } from "./declarations.js";
5
- import { OWNED_UI_SETTINGS_MIGRATIONS, normalizeOwnedUiSettingsValues, } from "./migrations.js";
6
- import { parseOwnedUiSettingsDocument, resolveOwnedUiSettings, } from "./resolution.js";
3
+ import { OWNED_SETTING_DECLARATIONS, OWNED_UI_SETTING_DECLARATIONS, } from "./declarations.js";
4
+ import { resolveOwnedUiSettings, } from "./resolution.js";
7
5
  import { buildOwnedUiSettingsSections, findOwnedUiSettingsEntry, } from "./sections.js";
8
6
  import { readProfileSettingsNamespace, repairProfileSettingsDocument, updateProfileSettingsNamespace, } from "./profile-document.js";
9
7
  const PROFILE_ID_PATTERN = /^[a-z][a-z0-9-]{0,63}$/;
@@ -16,10 +14,8 @@ const MAX_DOCUMENT_BYTES = 256 * 1024;
16
14
  */
17
15
  export class OwnedSettingsManager {
18
16
  #file;
19
- #legacyFile;
20
17
  #namespace;
21
18
  #declarations;
22
- #migrations;
23
19
  #agent;
24
20
  #agentProvider;
25
21
  #listeners = new Set();
@@ -38,12 +34,8 @@ export class OwnedSettingsManager {
38
34
  if (profileDir === undefined)
39
35
  throw new Error("owned UI settings require a profile directory");
40
36
  this.#file = path.join(path.resolve(profileDir), "settings.json");
41
- this.#legacyFile = options.legacyConfigDir === undefined
42
- ? null
43
- : path.join(path.resolve(options.legacyConfigDir), "settings", `${options.profileId}.json`);
44
37
  this.#namespace = options.namespace ?? options.profileId;
45
38
  this.#declarations = options.declarations ?? OWNED_UI_SETTING_DECLARATIONS;
46
- this.#migrations = options.migrations ?? OWNED_UI_SETTINGS_MIGRATIONS;
47
39
  this.#agent = options.agent ?? null;
48
40
  this.#agentProvider = options.agentProvider ?? null;
49
41
  this.#hiddenOwnedSettingIds = new Set(options.hiddenOwnedSettingIds ?? []);
@@ -74,53 +66,15 @@ export class OwnedSettingsManager {
74
66
  if (Buffer.byteLength(JSON.stringify(shared.value), "utf8") > MAX_DOCUMENT_BYTES) {
75
67
  return this.#resolveNamespace(null, `${this.#file} contains a ${this.#namespace} namespace exceeding the ${MAX_DOCUMENT_BYTES}-byte settings limit`);
76
68
  }
77
- return this.#resolveCompatibleNamespace(shared.value);
69
+ return this.#resolveNamespace(shared.value);
78
70
  }
79
- if (shared.status === "invalid")
80
- return this.#resolveNamespace(null, shared.detail);
81
- return this.#readLegacy();
82
- }
83
- #resolveCompatibleNamespace(values) {
84
- const compatibility = normalizeOwnedUiSettingsValues(values);
85
- return compatibility.values === null
86
- ? this.#resolveNamespace(null, compatibility.failure ?? "product settings compatibility failed")
87
- : this.#resolveNamespace(compatibility.values);
71
+ return this.#resolveNamespace(null, shared.status === "invalid" ? shared.detail : undefined);
88
72
  }
89
73
  #resolveNamespace(values, unreadableDetail) {
90
74
  return resolveOwnedUiSettings({
91
75
  declarations: this.#declarations,
92
- migrations: [],
93
- document: values === null ? null : { version: OWNED_UI_SETTINGS_VERSION, values },
76
+ values,
94
77
  ...(unreadableDetail === undefined ? {} : { unreadableDetail }),
95
- currentVersion: OWNED_UI_SETTINGS_VERSION,
96
- });
97
- }
98
- #readLegacy() {
99
- if (this.#legacyFile === null)
100
- return this.#resolveNamespace(null);
101
- let raw = null;
102
- let unreadable = null;
103
- try {
104
- raw = readFileSync(this.#legacyFile, "utf8");
105
- }
106
- catch (error) {
107
- if (!isMissing(error))
108
- unreadable = `${this.#legacyFile} could not be read: ${describe(error)}`;
109
- }
110
- if (raw !== null && Buffer.byteLength(raw, "utf8") > MAX_DOCUMENT_BYTES) {
111
- unreadable = `${this.#legacyFile} exceeds the ${MAX_DOCUMENT_BYTES}-byte settings limit and was ignored`;
112
- raw = null;
113
- }
114
- const document = raw === null ? null : parseOwnedUiSettingsDocument(raw);
115
- if (raw !== null && document === null && unreadable === null) {
116
- unreadable = `${this.#legacyFile} is not a valid settings document and was ignored`;
117
- }
118
- return resolveOwnedUiSettings({
119
- declarations: this.#declarations,
120
- migrations: this.#migrations,
121
- document,
122
- ...(unreadable === null ? {} : { unreadableDetail: unreadable }),
123
- currentVersion: OWNED_UI_SETTINGS_VERSION,
124
78
  });
125
79
  }
126
80
  async load() {
@@ -231,14 +185,7 @@ export class OwnedSettingsManager {
231
185
  }
232
186
  try {
233
187
  updateProfileSettingsNamespace(this.#file, this.#namespace, current => {
234
- let latest = this.#readLegacy();
235
- if (current !== null) {
236
- const compatibility = normalizeOwnedUiSettingsValues(current);
237
- if (compatibility.values === null)
238
- throw new Error(compatibility.failure ?? "product settings compatibility failed");
239
- latest = this.#resolveNamespace(compatibility.values);
240
- }
241
- const next = compactValues(latest);
188
+ const next = compactValues(this.#resolveNamespace(current));
242
189
  if (value === declaration.defaultValue)
243
190
  delete next[id];
244
191
  else
@@ -343,9 +290,6 @@ function compactValues(resolution) {
343
290
  }
344
291
  return values;
345
292
  }
346
- function isMissing(error) {
347
- return typeof error === "object" && error !== null && error.code === "ENOENT";
348
- }
349
293
  function describe(error) {
350
294
  return error instanceof Error ? error.message : String(error);
351
295
  }
@@ -1,12 +1,11 @@
1
1
  import { type OwnedUiSettingDeclaration, type OwnedUiSettingValue } from "./declarations.js";
2
- import { type OwnedUiSettingsMigration } from "./migrations.js";
3
2
  export type OwnedUiSettingSource = "default" | "stored";
4
3
  export interface OwnedUiResolvedSetting {
5
4
  readonly declaration: OwnedUiSettingDeclaration;
6
5
  readonly value: OwnedUiSettingValue;
7
6
  readonly source: OwnedUiSettingSource;
8
7
  }
9
- export type OwnedUiSettingsNoticeCode = "document-unreadable" | "version-newer-than-supported" | "migration-unavailable" | "value-rejected";
8
+ export type OwnedUiSettingsNoticeCode = "document-unreadable" | "value-rejected";
10
9
  export interface OwnedUiSettingsNotice {
11
10
  readonly code: OwnedUiSettingsNoticeCode;
12
11
  /** Setting id for a rejected value; null for document-level notices. */
@@ -14,32 +13,21 @@ export interface OwnedUiSettingsNotice {
14
13
  readonly detail: string;
15
14
  }
16
15
  export interface OwnedUiSettingsResolution {
17
- readonly version: number;
18
16
  readonly settings: readonly OwnedUiResolvedSetting[];
19
17
  /** Keys that match no declaration, preserved verbatim so a downgrade cannot destroy them. */
20
18
  readonly preserved: Readonly<Record<string, unknown>>;
21
19
  readonly notices: readonly OwnedUiSettingsNotice[];
22
- /** True when the resolved form differs from what was stored and should be written on the next change. */
23
- readonly migrated: boolean;
24
20
  }
25
- export interface OwnedUiSettingsDocument {
26
- readonly version: number;
27
- readonly values: Readonly<Record<string, unknown>>;
28
- }
29
- export declare function parseOwnedUiSettingsDocument(raw: string): OwnedUiSettingsDocument | null;
30
21
  export interface ResolveOwnedUiSettingsInput {
31
22
  readonly declarations: readonly OwnedUiSettingDeclaration[];
32
- readonly migrations: readonly OwnedUiSettingsMigration[];
33
- /** Parsed document, or null when the file is absent, unreadable, or unparseable. */
34
- readonly document: OwnedUiSettingsDocument | null;
35
- /** Set when the document existed but could not be read or parsed. */
23
+ /** Stored values, or null when the namespace is absent, unreadable, or unparseable. */
24
+ readonly values: Readonly<Record<string, unknown>> | null;
25
+ /** Set when the stored values existed but could not be read or parsed. */
36
26
  readonly unreadableDetail?: string;
37
- readonly currentVersion?: number;
38
27
  }
39
28
  /**
40
- * Pure resolution: declarations plus a parsed document produce a complete value
41
- * set, the keys to preserve, and every notice worth reporting. Never throws.
29
+ * Pure resolution: declarations plus stored values produce a complete value set, the keys to
30
+ * preserve, and every notice worth reporting. Never throws.
42
31
  */
43
32
  export declare function resolveOwnedUiSettings(input: ResolveOwnedUiSettingsInput): OwnedUiSettingsResolution;
44
33
  export declare function settingValue(resolution: OwnedUiSettingsResolution, id: string): OwnedUiSettingValue | null;
45
- export declare function documentFrom(resolution: OwnedUiSettingsResolution): OwnedUiSettingsDocument;
@@ -1,93 +1,14 @@
1
- import { OWNED_UI_SETTINGS_VERSION, findOwnedUiSettingDeclaration, } from "./declarations.js";
2
- import { migrationsFrom } from "./migrations.js";
3
- export function parseOwnedUiSettingsDocument(raw) {
4
- let parsed;
5
- try {
6
- parsed = JSON.parse(raw);
7
- }
8
- catch {
9
- return null;
10
- }
11
- if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
12
- return null;
13
- const candidate = parsed;
14
- const version = candidate["version"];
15
- if (typeof version !== "number" || !Number.isInteger(version) || version < 1)
16
- return null;
17
- const values = candidate["values"];
18
- if (typeof values !== "object" || values === null || Array.isArray(values))
19
- return null;
20
- return { version, values: values };
21
- }
1
+ import { findOwnedUiSettingDeclaration, } from "./declarations.js";
22
2
  /**
23
- * Pure resolution: declarations plus a parsed document produce a complete value
24
- * set, the keys to preserve, and every notice worth reporting. Never throws.
3
+ * Pure resolution: declarations plus stored values produce a complete value set, the keys to
4
+ * preserve, and every notice worth reporting. Never throws.
25
5
  */
26
6
  export function resolveOwnedUiSettings(input) {
27
- const currentVersion = input.currentVersion ?? OWNED_UI_SETTINGS_VERSION;
28
7
  const notices = [];
29
8
  if (input.unreadableDetail !== undefined) {
30
9
  notices.push({ code: "document-unreadable", settingId: null, detail: input.unreadableDetail });
31
10
  }
32
- if (input.document === null) {
33
- return {
34
- version: currentVersion,
35
- settings: defaultsFor(input.declarations),
36
- preserved: Object.freeze({}),
37
- notices: Object.freeze(notices),
38
- migrated: false,
39
- };
40
- }
41
- if (input.document.version > currentVersion) {
42
- notices.push({
43
- code: "version-newer-than-supported",
44
- settingId: null,
45
- detail: `stored version ${input.document.version} is newer than supported version ${currentVersion}`,
46
- });
47
- return {
48
- version: currentVersion,
49
- settings: defaultsFor(input.declarations),
50
- preserved: Object.freeze({ ...input.document.values }),
51
- notices: Object.freeze(notices),
52
- migrated: false,
53
- };
54
- }
55
- const pending = migrationsFrom(input.migrations, input.document.version);
56
- const expected = currentVersion - input.document.version;
57
- if (pending.length !== expected) {
58
- notices.push({
59
- code: "migration-unavailable",
60
- settingId: null,
61
- detail: `no declared migration path from stored version ${input.document.version} to ${currentVersion}`,
62
- });
63
- return {
64
- version: currentVersion,
65
- settings: defaultsFor(input.declarations),
66
- preserved: Object.freeze({ ...input.document.values }),
67
- notices: Object.freeze(notices),
68
- migrated: false,
69
- };
70
- }
71
- let values = { ...input.document.values };
72
- for (const migration of pending) {
73
- try {
74
- values = { ...migration.migrate(Object.freeze({ ...values })) };
75
- }
76
- catch (error) {
77
- notices.push({
78
- code: "migration-unavailable",
79
- settingId: null,
80
- detail: `migration to version ${migration.to} failed: ${describe(error)}`,
81
- });
82
- return {
83
- version: currentVersion,
84
- settings: defaultsFor(input.declarations),
85
- preserved: Object.freeze({ ...input.document.values }),
86
- notices: Object.freeze(notices),
87
- migrated: false,
88
- };
89
- }
90
- }
11
+ const values = input.values ?? {};
91
12
  const settings = [];
92
13
  for (const declaration of input.declarations) {
93
14
  if (!Object.hasOwn(values, declaration.id)) {
@@ -112,36 +33,16 @@ export function resolveOwnedUiSettings(input) {
112
33
  preserved[key] = value;
113
34
  }
114
35
  return {
115
- version: currentVersion,
116
36
  settings: Object.freeze(settings),
117
37
  preserved: Object.freeze(preserved),
118
38
  notices: Object.freeze(notices),
119
- migrated: pending.length > 0,
120
39
  };
121
40
  }
122
41
  export function settingValue(resolution, id) {
123
42
  return resolution.settings.find(setting => setting.declaration.id === id)?.value ?? null;
124
43
  }
125
- export function documentFrom(resolution) {
126
- const values = { ...resolution.preserved };
127
- for (const setting of resolution.settings) {
128
- if (setting.source === "stored")
129
- values[setting.declaration.id] = setting.value;
130
- }
131
- return { version: resolution.version, values };
132
- }
133
- function defaultsFor(declarations) {
134
- return Object.freeze(declarations.map(declaration => ({
135
- declaration,
136
- value: declaration.defaultValue,
137
- source: "default",
138
- })));
139
- }
140
44
  function isAllowed(declaration, value) {
141
45
  if (typeof value !== "string" && typeof value !== "number" && typeof value !== "boolean")
142
46
  return false;
143
47
  return declaration.allowedValues.includes(value);
144
48
  }
145
- function describe(error) {
146
- return error instanceof Error ? error.message : String(error);
147
- }
@@ -49,8 +49,4 @@ export interface BuildOwnedUiSettingsSectionsInput {
49
49
  }
50
50
  export declare const AGENT_SECTION_ID = "agent";
51
51
  export declare function buildOwnedUiSettingsSections(input: BuildOwnedUiSettingsSectionsInput): readonly OwnedUiSettingsSection[];
52
- /** The enabled parts a flagged A1 setting's comma-separated value names, as the record its dialog edits. */
53
- export declare function flagRecord(flags: readonly {
54
- readonly key: string;
55
- }[], value: unknown): Record<string, boolean>;
56
52
  export declare function findOwnedUiSettingsEntry(sections: readonly OwnedUiSettingsSection[], id: string, backend: OwnedUiSettingsBackend): OwnedUiSettingsEntry | null;
@@ -46,7 +46,7 @@ export function buildOwnedUiSettingsSections(input) {
46
46
  return Object.freeze([...ownedSections, combinedAgent]);
47
47
  }
48
48
  /** The enabled parts a flagged A1 setting's comma-separated value names, as the record its dialog edits. */
49
- export function flagRecord(flags, value) {
49
+ function flagRecord(flags, value) {
50
50
  const enabled = new Set(typeof value === "string" ? value.split(",") : []);
51
51
  return Object.fromEntries(flags.map(flag => [flag.key, enabled.has(flag.key)]));
52
52
  }
@@ -29,7 +29,7 @@ The owned Pi-backed surface is one agent per terminal. It is not a terminal mult
29
29
  - `prompt-history`: narrowly typed user-input retention in separate profile-owned databases under `~/.a1/data/history` (or `<A1_DATA_DIR>/history`), with bounded worker queues. It receives a resolved root rather than importing launch-feature internals; it never probes, imports, or deletes the former platform-default history. The editor's owned history state machine remains inside the Pi component boundary; the session UI only coordinates snapshots and classified submissions.
30
30
  - `prompt-suggestions`: opt-in bounded diagnostic snapshots of neutral suggestion lifecycle metadata. Composition supplies an explicit local destination; this feature never imports Pi, generates suggestions, stores conversation text, or owns the editor. See [prompt suggestion diagnostics](prompt-suggestions.md).
31
31
  - `pi-engine-adapter`, `pi-component-adapter`, and `pi-tui-runtime-adapter` (`src/integrations/pi`): isolate pinned Pi engine and presentation knowledge behind neutral contracts; product features do not import them directly. Inside the engine adapter, one process-level engine host owns what is process-wide (the HTTP dispatcher, the theme singletons, the one-time changelog and package-update announcements, the startup trace) and is the only place sessions are created, so every session id is unique per process.
32
- - `session-shell` (`src/app/session-shell`): the application layer that composes the feature owners, the UI foundations, and the three Pi adapters into the interactive session; only composition imports it. Its render root assembles semantic document and dock rows, while its focused viewport controller owns follow state, pointer routing, selection, and interaction timers. Owned-app route lifecycle belongs to the neutral `ui-apps` owner and is only hosted by the session shell.
32
+ - `session-shell` (`src/app/session-shell`): the application layer that composes the feature owners and the UI foundations into the interactive session; it reaches Pi only through the owned-UI and presentation contracts, and only composition imports it. Its render root assembles semantic document and dock rows, while its focused viewport controller owns follow state, pointer routing, selection, and interaction timers. Owned-app route lifecycle belongs to the neutral `ui-apps` owner and is only hosted by the session shell.
33
33
 
34
34
  ## Dependency direction
35
35
 
@@ -41,7 +41,7 @@ The product has no native code and no PTY or terminal-emulator dependency: no mo
41
41
 
42
42
  ## Session shell composition
43
43
 
44
- The session presenter (`src/app/session-shell/session-shell.ts`) coordinates; it does not own per-concern state. Each concern implements `SessionConcern` (`session-concern.ts`): it resets its own state in `onSessionReplaced` and releases it in `dispose`, and the presenter lists its concerns once, in reset order, in `#createConcerns`. New submission, routing, dialog, or login behavior goes into the concern that owns it, or a new concern added to that list. The render root (`session-shell-root.ts`) likewise picks one `ShellLayout` at construction and delegates transcript caching to `TranscriptDocument`, dock chrome to `DockChrome`, workflow output to `WorkflowOutput`, extension surfaces to `ExtensionSurface`, and the dock's input surface to `InputSurfaceSwitch`. The engine adapter serves the shell through the ports built in `src/integrations/pi/engine/ports.ts`, and the composition root delegates runtime claims and the startup release note to their own modules under `src/composition/`.
44
+ The session presenter (`src/app/session-shell/session-shell.ts`) coordinates; it does not own per-concern state. Each concern implements `SessionConcern` (`session-concern.ts`): it resets its own state in `onSessionReplaced` and releases it in `dispose`, and the presenter lists its concerns once, in reset order, in `#createConcerns`. New submission, routing, dialog, or login behavior goes into the concern that owns it, or a new concern added to that list. One shell's clipboard wiring is `ShellClipboard` (it borrows the process-wide helper pools composition creates), prompt suggestions are `ShellPromptSuggestions`, and the shell's own setting sources bind through `bindShellSettings`. The render root (`session-shell-root.ts`) likewise picks one `ShellLayout` at construction and exposes its parts to callers directly: transcript caching is `root.transcript` (`TranscriptDocument`), dock chrome is `root.chrome` (`DockChrome`), workflow output is `root.workflow` (`WorkflowOutput`); it also delegates extension surfaces to `ExtensionSurface`, and the dock's input surface to `InputSurfaceSwitch`. The engine adapter serves the shell through the ports built in `src/integrations/pi/engine/ports.ts`, and the composition root delegates runtime claims and the startup release note to their own modules under `src/composition/`.
45
45
 
46
46
  ## Unit size ratchet
47
47
 
@@ -66,6 +66,8 @@ The old environment registry included `fixture` and `inputAcknowledgement`, but
66
66
 
67
67
  `certificationTarball`, `internalPackaging`, `nativePi`, `piParityIntentionalMutation`, `protocolVersion`, `structuredFlowLimits`, `terminalArgumentsJson`, and `terminalExecutable` had no active runtime consumer in the reviewed tree. They are removed from the current environment authority, not renamed into new settings. Rejection patterns and immutable historical evidence remain factual.
68
68
 
69
+ The release store (`src/foundation/release/release-state.ts`, persisted as `release-state.json`) keeps the schema id `a1-release-cohort-v1` and the identity key `releaseCohortSchema`. "Cohort" is a legacy name from the retired supervisor era; the id is unchanged because every installed release state carries it, and renaming it would make existing installations unreadable.
70
+
69
71
  ## Negotiated handoff and protected state
70
72
 
71
73
  An update is performed by the release that is already installed, so the contract is negotiated rather than cut over. `neutral-launch-v1` is the only contract this build **writes** for its own releases, and the superseded `A1_RELEASE_*`/`A1_IMMUTABLE_WARMUP` keys are still **read** when an older launcher starts this build, and still **written** when this build starts a retained release that declares no contract. An installation therefore stays launchable across the cutover in both directions, and no user is asked to stop processes and reinstall by hand.
@@ -37,12 +37,14 @@ src/
37
37
  ui/
38
38
  apps/ application registry and host lifecycle
39
39
  components/ vendor-neutral terminal UI primitives
40
- settings/ owned settings declarations, resolution, migration, and persistence
40
+ settings/ owned settings declarations, resolution, and persistence
41
41
  ```
42
42
 
43
43
  Each directory owner exposes `index.ts`, which lists its named exports; `export *` is rejected there so a public contract is readable in one place. Imports within one owner may use private files. Imports crossing owners must use the provider's public entry and follow the dependency DAG declared by `PROJECT_OWNERS`. Two exceptions exist: `src/composition` is the dependency-injection root and may reach past any public entry, and a module on the eager startup path may import a leaf of a provider whose public entry is a prohibited startup entry (`PROHIBITED_STARTUP_ENTRIES` in `startup-graph-policy.mjs`), because loading that barrel would pull the provider's whole graph into startup. `product-identity` is the sole exception to the directory-entry convention because its public entry is `src/product-identity.ts`.
44
44
 
45
- Three layer boundaries hold regardless of the DAG: `src/contracts/*` import nothing outside their own contract; `src/ui/components` imports only contracts; only `src/integrations/pi/*` and the shipped `bin/` entries import the pinned Pi packages. The session shell under `src/app` is the application layer: it may import the contracts, the UI foundations, the three Pi adapters, and the feature owners, and only composition imports it. The shell never holds a Pi engine object: selectors and transcript renderers built from one live in `src/integrations/pi/session-presenters`, the only owner besides composition that may import both the engine and the component adapters, and the shell opens them through the `OwnedUiSessionPresenters` contract.
45
+ Three layer boundaries hold regardless of the DAG: `src/contracts/*` import nothing outside their own contract; `src/ui/components` imports only contracts; only `src/integrations/pi/*` and the shipped `bin/` entries import the pinned Pi packages. The session shell under `src/app` is the application layer: it may import the contracts, the UI foundations, and the feature owners, never `src/integrations/pi`, and only composition imports it. Composition hands it one `OwnedUiSessionPresenters` value from `src/integrations/pi/session-presenters`: the theme and terminal runtime (`ShellPresentationPorts`), the component factories (`OwnedUiShellComponents`), and the engine-backed selectors. That owner is the only one besides composition that may import both the engine and the component adapters.
46
+
47
+ Every exported value under `src/` needs a production consumer: a file under `src/`, `bin/`, or `scripts/` that imports its module and names it. Owner public entries, declared entry modules, the product identity entry, copied upstream sources, and types are exempt. A value only a test reads stays private, and the test goes through the owner's public entry or an observable result.
46
48
 
47
49
  `src/cli` contains command policy but delegates runtime work. `src/composition` is the concrete dependency-injection boundary: it may know both neutral contracts and Pi implementations, while product features receive vendor-neutral ports. Foundation modules never import product features. Pi package knowledge remains inside the Pi adapter owners.
48
50
 
@@ -40,7 +40,7 @@ Do not run preflight, `test:fast`, `test:full`, `test:release`, or directory-wid
40
40
  npm run preflight # pull-request validation's fast gates on the committed head
41
41
  ```
42
42
 
43
- Preflight selects the committed merge-base diff with `origin/develop` exactly as validation does (uncommitted paths are reported, not checked), writes it to `.artifacts/validation/local-impact.json`, and stops at the first failure. It runs the core job's install build and receipt, `typecheck`, `check:architecture`, changed-file code documentation, release documentation, changed-file naming, docs governance, strict OpenSpec validation with the workflow's pinned validator, the delivery-guidance test, and the core job's `pr-core-tests` and `pr-selected-tests` scopes. Each step invokes the script and arguments its workflow job runs, so a failure reports the same rule identifier and path. It does not run resource-sensitive or integration owners, and CI remains the authority.
43
+ Preflight selects the committed merge-base diff with `origin/develop` exactly as validation does (uncommitted paths are reported, not checked), writes it to `.artifacts/validation/local-impact.json`, and stops at the first failure. It runs the core job's install build and receipt, `typecheck`, `check:architecture`, changed-file code documentation, release documentation, changed-file naming, docs governance, strict OpenSpec validation with the workflow's pinned validator, and the core job's `pr-core-tests` and `pr-selected-tests` scopes. Each step invokes the script and arguments its workflow job runs, so a failure reports the same rule identifier and path. It does not run resource-sensitive or integration owners, and CI remains the authority.
44
44
 
45
45
  `test:pr-core` is not a replacement for `test:fast`: CI combines it with directly changed and coarse-owner tests from the exact impact selection. Selected resource-sensitive tests run independently on an isolated Windows runner. Selected package, startup, rendering, Pi, compatibility, and platform owners also run independently after their actual prerequisites.
46
46
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timurproko/a1",
3
- "version": "0.2.7-dev.1252",
3
+ "version": "0.2.7-dev.1255",
4
4
  "description": "Standalone single-agent terminal UI on pinned Pi",
5
5
  "type": "module",
6
6
  "privateLaunchContract": "neutral-launch-v1",
@@ -89,7 +89,6 @@
89
89
  "@typescript/native-preview": "7.0.0-dev.20260707.2",
90
90
  "@xterm/headless": "6.0.0",
91
91
  "esbuild": "0.25.10",
92
- "node-pty": "1.1.0",
93
92
  "tsx": "4.20.3",
94
93
  "typescript": "5.9.2",
95
94
  "vitest": "3.2.7",
@@ -114,7 +113,7 @@
114
113
  "@mariozechner/clipboard": "^0.3.9"
115
114
  },
116
115
  "publication": {
117
- "source": "9f0307c00ea0b83cfd4aea196543ddb7738fc6ee",
118
- "pullRequest": 878
116
+ "source": "c42a37a9eb7e1c01d121f82a7be42376aaa7c542",
117
+ "pullRequest": 879
119
118
  }
120
119
  }
@@ -1,4 +0,0 @@
1
- import type { OwnedUiTranscriptBlock } from "../../../contracts/owned-ui/index.js";
2
- export declare function adaptPiUserMessage(block: OwnedUiTranscriptBlock, width: number): readonly string[];
3
- export declare function adaptPiAssistantMessage(block: OwnedUiTranscriptBlock, width: number): readonly string[];
4
- export declare function adaptPiToolExecution(block: OwnedUiTranscriptBlock, width: number, cwd: string): readonly string[];
@@ -1,48 +0,0 @@
1
- import { AssistantMessageComponent, ToolExecutionComponent, UserMessageComponent, } from "../startup-public.js";
2
- import { createTuiFacade, validatedAssistantMessage } from "./shell-components.js";
3
- import { ensurePiTheme, getPiMarkdownTheme } from "./theme.js";
4
- export function adaptPiUserMessage(block, width) {
5
- requireBlock(block, "user");
6
- ensurePiTheme();
7
- return new UserMessageComponent(block.text).render(width);
8
- }
9
- export function adaptPiAssistantMessage(block, width) {
10
- requireBlock(block, "assistant");
11
- ensurePiTheme();
12
- return new AssistantMessageComponent(validatedAssistantMessage(block), false, getPiMarkdownTheme()).render(width);
13
- }
14
- export function adaptPiToolExecution(block, width, cwd) {
15
- if (block.kind !== "tool-call" && block.kind !== "tool-result") {
16
- throw new TypeError("Pi tool execution adaptation requires a tool block");
17
- }
18
- ensurePiTheme();
19
- const payload = blockPayload(block);
20
- const toolCallId = stringPayload(payload, "toolCallId") ?? block.id;
21
- const toolName = stringPayload(payload, "toolName") ?? block.title ?? "tool";
22
- const args = isRecord(payload.arguments) && "json" in payload.arguments ? payload.arguments.json : {};
23
- const component = new ToolExecutionComponent(toolName, toolCallId, args, undefined, undefined, createTuiFacade({ getColumns: () => width, getRows: () => 24, requestRender() { } }), cwd);
24
- if (block.status === "live")
25
- component.markExecutionStarted();
26
- component.setArgsComplete();
27
- if (block.kind === "tool-result") {
28
- component.updateResult({
29
- content: [{ type: "text", text: block.text }],
30
- isError: payload.isError === true,
31
- });
32
- }
33
- return component.render(width);
34
- }
35
- function requireBlock(block, kind) {
36
- if (block.kind !== kind)
37
- throw new TypeError(`Pi component adaptation requires ${kind}, received ${block.kind}`);
38
- }
39
- function blockPayload(block) {
40
- return isRecord(block.payload) ? block.payload : {};
41
- }
42
- function stringPayload(payload, key) {
43
- const value = payload[key];
44
- return typeof value === "string" && value.length > 0 ? value : undefined;
45
- }
46
- function isRecord(value) {
47
- return typeof value === "object" && value !== null;
48
- }
@@ -1,18 +0,0 @@
1
- export interface PiComponentConformanceResult {
2
- readonly component: "user-message" | "assistant-message" | "tool-execution";
3
- readonly renderRows: number;
4
- readonly width: number;
5
- }
6
- export interface PiComponentConformanceReport {
7
- readonly packageName: "@earendil-works/pi-coding-agent";
8
- readonly packageVersion: string;
9
- readonly ownedUiContractVersion: number;
10
- readonly componentResults: readonly PiComponentConformanceResult[];
11
- readonly componentFamilies: readonly string[];
12
- }
13
- /** Identifies the Pi presentation-conformance stage that failed against the pinned component surface. */
14
- export declare class PiComponentConformanceError extends Error {
15
- readonly stage: "theme" | "components";
16
- constructor(stage: "theme" | "components", cause: unknown);
17
- }
18
- export declare function runPiComponentConformance(): Promise<PiComponentConformanceReport>;