@timurproko/a1 0.2.7-dev.754 → 0.2.7-dev.772

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 (217) hide show
  1. package/README.md +30 -0
  2. package/bin/cli.js +4 -0
  3. package/bin/guardian.js +5 -0
  4. package/bin/tab-launch-context.d.ts +26 -0
  5. package/bin/tab-launch-context.js +94 -0
  6. package/bin/ui.js +24 -6
  7. package/dist/app/session-shell/helper-pool.d.ts +3 -5
  8. package/dist/app/session-shell/helper-pool.js +3 -5
  9. package/dist/app/session-shell/session-shell-root.d.ts +28 -1
  10. package/dist/app/session-shell/session-shell-root.js +4 -3
  11. package/dist/app/session-shell/session-shell.js +149 -31
  12. package/dist/app/session-shell/session-viewport-controller.d.ts +1 -1
  13. package/dist/app/session-shell/session-viewport-controller.js +3 -3
  14. package/dist/app/session-shell/shell-host.d.ts +2 -0
  15. package/dist/app/session-shell/shell-host.js +20 -1
  16. package/dist/cli/dispatch.d.ts +11 -1
  17. package/dist/cli/dispatch.js +79 -5
  18. package/dist/cli/tabs-request.d.ts +7 -0
  19. package/dist/cli/tabs-request.js +1 -0
  20. package/dist/cli/tabs.d.ts +14 -0
  21. package/dist/cli/tabs.js +140 -0
  22. package/dist/composition/owned-ui.d.ts +26 -0
  23. package/dist/composition/owned-ui.js +176 -6
  24. package/dist/contracts/owned-ui/session-backend.d.ts +1 -0
  25. package/dist/features/launch/index.d.ts +1 -1
  26. package/dist/features/launch/intent.d.ts +3 -1
  27. package/dist/features/launch/intent.js +7 -4
  28. package/dist/features/owned-ui/settings-app.js +8 -35
  29. package/dist/features/resident-tab/auto-name.d.ts +11 -0
  30. package/dist/features/resident-tab/auto-name.js +42 -0
  31. package/dist/features/resident-tab/index.d.ts +3 -0
  32. package/dist/features/resident-tab/index.js +3 -0
  33. package/dist/features/resident-tab/shortcuts.d.ts +10 -0
  34. package/dist/features/resident-tab/shortcuts.js +35 -0
  35. package/dist/features/resident-tab/status-deriver.d.ts +9 -0
  36. package/dist/features/resident-tab/status-deriver.js +15 -0
  37. package/dist/foundation/launch-context/index.d.ts +10 -0
  38. package/dist/foundation/launch-context/index.js +25 -0
  39. package/dist/foundation/launch-guardian/main.d.ts +5 -0
  40. package/dist/foundation/launch-guardian/main.js +2 -1
  41. package/dist/foundation/release/bootstrap.d.ts +6 -0
  42. package/dist/foundation/release/bootstrap.js +51 -10
  43. package/dist/foundation/release/cohort-state.d.ts +1 -1
  44. package/dist/foundation/release/cohort-state.js +1 -1
  45. package/dist/foundation/release/dependency-certification.js +54 -19
  46. package/dist/foundation/release/progress-palette.generated.d.ts +2 -2
  47. package/dist/foundation/release/progress-palette.generated.js +2 -2
  48. package/dist/foundation/release/release-gc.d.ts +3 -0
  49. package/dist/foundation/release/release-gc.js +44 -8
  50. package/dist/foundation/resident-tabs/bounded-host-command.d.ts +16 -0
  51. package/dist/foundation/resident-tabs/bounded-host-command.js +35 -0
  52. package/dist/foundation/resident-tabs/bridge-client.d.ts +56 -0
  53. package/dist/foundation/resident-tabs/bridge-client.js +279 -0
  54. package/dist/foundation/resident-tabs/doctor.d.ts +29 -0
  55. package/dist/foundation/resident-tabs/doctor.js +166 -0
  56. package/dist/foundation/resident-tabs/draft-checkpoint.d.ts +27 -0
  57. package/dist/foundation/resident-tabs/draft-checkpoint.js +145 -0
  58. package/dist/foundation/resident-tabs/ensure-terminal-host.d.ts +31 -0
  59. package/dist/foundation/resident-tabs/ensure-terminal-host.js +147 -0
  60. package/dist/foundation/resident-tabs/fault-injection.d.ts +8 -0
  61. package/dist/foundation/resident-tabs/fault-injection.js +26 -0
  62. package/dist/foundation/resident-tabs/index.d.ts +12 -0
  63. package/dist/foundation/resident-tabs/index.js +6 -0
  64. package/dist/foundation/resident-tabs/maintenance.d.ts +42 -0
  65. package/dist/foundation/resident-tabs/maintenance.js +78 -0
  66. package/dist/foundation/resident-tabs/prompt-journal.d.ts +65 -0
  67. package/dist/foundation/resident-tabs/prompt-journal.js +214 -0
  68. package/dist/foundation/resident-tabs/protocol.d.ts +12 -0
  69. package/dist/foundation/resident-tabs/protocol.js +195 -0
  70. package/dist/foundation/resident-tabs/recovery.d.ts +26 -0
  71. package/dist/foundation/resident-tabs/recovery.js +205 -0
  72. package/dist/foundation/resident-tabs/release-holds.d.ts +27 -0
  73. package/dist/foundation/resident-tabs/release-holds.js +77 -0
  74. package/dist/foundation/resident-tabs/routing.d.ts +11 -0
  75. package/dist/foundation/resident-tabs/routing.js +10 -0
  76. package/dist/foundation/resident-tabs/session-sync.d.ts +14 -0
  77. package/dist/foundation/resident-tabs/session-sync.js +37 -0
  78. package/dist/foundation/resident-tabs/settings.d.ts +14 -0
  79. package/dist/foundation/resident-tabs/settings.js +66 -0
  80. package/dist/foundation/resident-tabs/terminal-host-artifact.d.ts +18 -0
  81. package/dist/foundation/resident-tabs/terminal-host-artifact.js +53 -0
  82. package/dist/foundation/resident-tabs/zip-archive.d.ts +9 -0
  83. package/dist/foundation/resident-tabs/zip-archive.js +56 -0
  84. package/dist/foundation/session-writer-lock/index.d.ts +32 -0
  85. package/dist/foundation/session-writer-lock/index.js +201 -0
  86. package/dist/foundation/startup/startup-descriptor.js +2 -2
  87. package/dist/foundation/terminal-cleanup/index.d.ts +1 -1
  88. package/dist/foundation/terminal-cleanup/index.js +1 -1
  89. package/dist/foundation/terminal-cleanup/terminal-reset.d.ts +1 -0
  90. package/dist/foundation/terminal-cleanup/terminal-reset.js +1 -0
  91. package/dist/integrations/pi/components/owned-editor-ux.d.ts +1 -1
  92. package/dist/integrations/pi/components/owned-editor-ux.js +2 -2
  93. package/dist/integrations/pi/components/resources/builtin-themes.d.ts +4 -4
  94. package/dist/integrations/pi/components/resources/builtin-themes.js +4 -4
  95. package/dist/integrations/pi/components/shell-hotkey-sections.js +1 -1
  96. package/dist/integrations/pi/components/shell-presenters-info.d.ts +4 -2
  97. package/dist/integrations/pi/components/shell-presenters-info.js +38 -4
  98. package/dist/integrations/pi/components/shell-shared-facade.d.ts +1 -1
  99. package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.d.ts +1 -1
  100. package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.js +17 -4
  101. package/dist/integrations/pi/components/upstream/assets/earendil-image.json +2 -2
  102. package/dist/integrations/pi/components/upstream/components/countdown-timer.d.ts +1 -1
  103. package/dist/integrations/pi/components/upstream/components/earendil-announcement.js +1 -1
  104. package/dist/integrations/pi/components/upstream/components/extension-editor.d.ts +1 -1
  105. package/dist/integrations/pi/components/upstream/components/extension-editor.js +1 -1
  106. package/dist/integrations/pi/components/upstream/components/extension-input.js +1 -1
  107. package/dist/integrations/pi/components/upstream/components/extension-selector.js +1 -1
  108. package/dist/integrations/pi/components/upstream/components/mermaid.js +1 -1
  109. package/dist/integrations/pi/components/upstream/components/owned-editor.d.ts +1 -1
  110. package/dist/integrations/pi/components/upstream/components/owned-editor.js +1 -1
  111. package/dist/integrations/pi/components/upstream/components/pi-logo.js +1 -1
  112. package/dist/integrations/pi/components/upstream/components/scoped-models-selector.d.ts +1 -1
  113. package/dist/integrations/pi/components/upstream/components/session-footer.js +1 -1
  114. package/dist/integrations/pi/components/upstream/components/session-selector-search.js +1 -1
  115. package/dist/integrations/pi/components/upstream/components/session-selector.js +1 -1
  116. package/dist/integrations/pi/components/upstream/components/skill-invocation-message.d.ts +1 -1
  117. package/dist/integrations/pi/components/upstream/components/skill-invocation-message.js +1 -1
  118. package/dist/integrations/pi/components/upstream/components/status-indicator.d.ts +2 -2
  119. package/dist/integrations/pi/components/upstream/components/status-indicator.js +3 -3
  120. package/dist/integrations/pi/components/upstream/components/themed-text.d.ts +1 -1
  121. package/dist/integrations/pi/components/upstream/components/themed-text.js +1 -1
  122. package/dist/integrations/pi/components/upstream/components/thinking-selector.d.ts +1 -1
  123. package/dist/integrations/pi/components/upstream/components/thinking-selector.js +1 -1
  124. package/dist/integrations/pi/components/upstream/components/tool-execution.d.ts +0 -2
  125. package/dist/integrations/pi/components/upstream/components/tool-execution.js +41 -20
  126. package/dist/integrations/pi/components/upstream/components/tree-selector.d.ts +1 -1
  127. package/dist/integrations/pi/components/upstream/components/tree-selector.js +1 -1
  128. package/dist/integrations/pi/components/upstream/components/trust-selector.js +1 -1
  129. package/dist/integrations/pi/components/upstream/external-editor.js +1 -1
  130. package/dist/integrations/pi/components/upstream/history/editor-core.d.ts +2 -2
  131. package/dist/integrations/pi/components/upstream/history/editor-core.js +5 -5
  132. package/dist/integrations/pi/components/upstream/history/kill-ring.d.ts +1 -1
  133. package/dist/integrations/pi/components/upstream/history/kill-ring.js +1 -1
  134. package/dist/integrations/pi/components/upstream/history/printable-key.js +1 -1
  135. package/dist/integrations/pi/components/upstream/history/text-helpers.js +1 -1
  136. package/dist/integrations/pi/components/upstream/history/undo-stack.d.ts +1 -1
  137. package/dist/integrations/pi/components/upstream/history/undo-stack.js +1 -1
  138. package/dist/integrations/pi/components/upstream/history/word-navigation.js +1 -1
  139. package/dist/integrations/pi/components/upstream/model-search.d.ts +1 -1
  140. package/dist/integrations/pi/components/upstream/program-status-reporter.d.ts +1 -1
  141. package/dist/integrations/pi/components/upstream/theme/theme-controller.d.ts +1 -1
  142. package/dist/integrations/pi/components/upstream/theme/theme.d.ts +3 -0
  143. package/dist/integrations/pi/components/upstream/theme/theme.js +24 -1
  144. package/dist/integrations/pi/engine/adapter.d.ts +1 -0
  145. package/dist/integrations/pi/engine/adapter.js +4 -0
  146. package/dist/integrations/pi/engine/pi-settings-metadata.json +2 -2
  147. package/dist/integrations/pi/engine/prompt-suggestions.d.ts +1 -0
  148. package/dist/integrations/pi/engine/prompt-suggestions.js +40 -0
  149. package/dist/integrations/pi/engine/resources/changelog.json +4 -4
  150. package/dist/integrations/pi/engine/runtime-integration.js +102 -29
  151. package/dist/integrations/pi/engine/session-runtime.d.ts +0 -6
  152. package/dist/integrations/pi/engine/session-runtime.js +8 -3
  153. package/dist/integrations/pi/engine/session-selection.d.ts +3 -0
  154. package/dist/integrations/pi/engine/session-selection.js +45 -9
  155. package/dist/integrations/pi/engine/workflow-contexts.js +10 -1
  156. package/dist/integrations/pi/startup-public.js +152 -222
  157. package/dist/integrations/pi/startup-public.manifest.json +266 -177
  158. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +1 -1
  159. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.js +1 -1
  160. package/dist/native/darwin-arm64/a1_session_lock.node +0 -0
  161. package/dist/native/darwin-arm64/manifest.json +1 -1
  162. package/dist/native/darwin-arm64/terminal-host +0 -0
  163. package/dist/native/darwin-arm64/terminal-host-THIRD-PARTY-NOTICES.txt +10500 -0
  164. package/dist/native/darwin-arm64/terminal-host.manifest.json +44 -0
  165. package/dist/native/darwin-x64/a1_session_lock.node +0 -0
  166. package/dist/native/darwin-x64/manifest.json +20 -0
  167. package/dist/native/darwin-x64/process-guardian +0 -0
  168. package/dist/native/darwin-x64/terminal-host +0 -0
  169. package/dist/native/darwin-x64/terminal-host-THIRD-PARTY-NOTICES.txt +10737 -0
  170. package/dist/native/darwin-x64/terminal-host.manifest.json +44 -0
  171. package/dist/native/linux-x64/a1_session_lock.node +0 -0
  172. package/dist/native/linux-x64/manifest.json +1 -1
  173. package/dist/native/linux-x64/terminal-host +0 -0
  174. package/dist/native/linux-x64/terminal-host-THIRD-PARTY-NOTICES.txt +11226 -0
  175. package/dist/native/linux-x64/terminal-host.manifest.json +44 -0
  176. package/dist/native/win32-x64/a1_session_lock.node +0 -0
  177. package/dist/native/win32-x64/manifest.json +2 -2
  178. package/dist/native/win32-x64/process-guardian.exe +0 -0
  179. package/dist/native/win32-x64/terminal-host-THIRD-PARTY-NOTICES.txt +10757 -0
  180. package/dist/native/win32-x64/terminal-host.exe +0 -0
  181. package/dist/native/win32-x64/terminal-host.manifest.json +44 -0
  182. package/dist/product-identity.d.ts +1 -1
  183. package/dist/product-identity.js +1 -1
  184. package/dist/product-identity.json +5 -0
  185. package/dist/runtime-payload-inventory.json +5349 -6035
  186. package/dist/ui/components/line-input.d.ts +1 -1
  187. package/dist/ui/components/prompt-input.d.ts +7 -5
  188. package/dist/ui/components/prompt-input.js +7 -7
  189. package/dist/ui/components/transcript-viewport.d.ts +6 -3
  190. package/dist/ui/components/transcript-viewport.js +13 -15
  191. package/dist/ui/settings/declarations.d.ts +25 -1
  192. package/dist/ui/settings/declarations.js +21 -1
  193. package/dist/ui/settings/index.d.ts +4 -2
  194. package/dist/ui/settings/index.js +2 -1
  195. package/dist/ui/settings/manager.d.ts +10 -3
  196. package/dist/ui/settings/manager.js +90 -30
  197. package/dist/ui/settings/migrations.d.ts +6 -0
  198. package/dist/ui/settings/migrations.js +44 -0
  199. package/dist/ui/settings/profile-document.d.ts +26 -0
  200. package/dist/ui/settings/profile-document.js +164 -0
  201. package/docs/architecture/evidence/resident-tabs/linux-x64.md +37 -0
  202. package/docs/architecture/evidence/resident-tabs/macos-arm64.md +36 -0
  203. package/docs/architecture/evidence/resident-tabs/macos-x64.md +35 -0
  204. package/docs/architecture/evidence/resident-tabs/windows-x64.md +36 -0
  205. package/docs/architecture/internal-naming.md +3 -1
  206. package/docs/architecture/process-guardian-provenance.md +2 -0
  207. package/docs/architecture/resident-tabs-requirements.md +18 -0
  208. package/docs/architecture/resident-tabs.md +594 -0
  209. package/docs/architecture/terminal-host-proof-gate.md +2 -0
  210. package/docs/architecture/terminal-host-provenance.md +13 -3
  211. package/docs/architecture/toolchain.md +1 -1
  212. package/docs/ci-release-runbook.md +2 -2
  213. package/docs/features/launch-profiles.md +11 -8
  214. package/docs/manual-resident-tabs-acceptance.md +51 -0
  215. package/docs/openspec-archive-automation.md +17 -16
  216. package/docs/validation.md +9 -1
  217. package/package.json +10 -4
@@ -0,0 +1,201 @@
1
+ import { closeSync, existsSync, mkdirSync, openSync, readFileSync, realpathSync, rmSync, statSync, writeFileSync } from "node:fs";
2
+ import { createRequire } from "node:module";
3
+ import { tmpdir } from "node:os";
4
+ import { basename, dirname, join, resolve } from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+ import { createHash } from "node:crypto";
7
+ import { PRODUCT_IDENTITY } from "../../product-identity.js";
8
+ /** Reports that a canonical session identity already has a live writer. */
9
+ export class SessionWriterConflict extends Error {
10
+ path;
11
+ holderKind;
12
+ constructor(path, holderKind = "another A1 process") {
13
+ super(`session is open in ${holderKind}`);
14
+ this.name = "SessionWriterConflict";
15
+ this.path = path;
16
+ this.holderKind = holderKind;
17
+ }
18
+ }
19
+ let backendOverride;
20
+ let cachedBackend;
21
+ /** Development-only override naming a native lock addon to load first. */
22
+ export const SESSION_LOCK_OVERRIDE_ENVIRONMENT = "A1_SESSION_LOCK_PATH";
23
+ /** Security: a release that carries its own lock never loads an addon chosen by the environment or cwd. */
24
+ export function nativeCandidates(moduleUrl = import.meta.url, env = process.env, cwd = process.cwd(), exists = existsSync) {
25
+ const addon = "a1_session_lock.node";
26
+ // Invariant: this module sits at dist/foundation/session-writer-lock/ inside the release root.
27
+ const own = resolve(fileURLToPath(new URL("../../../", moduleUrl)), "dist", "native", `${process.platform}-${process.arch}`, addon);
28
+ const override = env[PRODUCT_IDENTITY.environment.developmentInstanceId] ? env[SESSION_LOCK_OVERRIDE_ENVIRONMENT]?.trim() || undefined : undefined;
29
+ const local = exists(own) ? [own] : [resolve(cwd, "dist", "native", `${process.platform}-${process.arch}`, addon), resolve(cwd, ".artifacts", "terminal-host", addon)];
30
+ return override ? [override, ...local] : local;
31
+ }
32
+ function loadNativeBackend() {
33
+ const require = createRequire(import.meta.url);
34
+ for (const candidate of nativeCandidates()) {
35
+ if (!existsSync(candidate))
36
+ continue;
37
+ try {
38
+ const loaded = require(candidate);
39
+ if (loaded.SessionLock?.acquire)
40
+ return loaded.SessionLock;
41
+ }
42
+ catch {
43
+ // Compatibility: an addon for another Node ABI is unusable; try the next location.
44
+ }
45
+ }
46
+ return undefined;
47
+ }
48
+ function processIsLive(pid) {
49
+ try {
50
+ process.kill(pid, 0);
51
+ return true;
52
+ }
53
+ catch {
54
+ return false;
55
+ }
56
+ }
57
+ /** Development fallback. Installed releases carry the verified Node-API lock resolved above. */
58
+ function portableBackend() {
59
+ const root = join(tmpdir(), "a1-session-writer-locks");
60
+ mkdirSync(root, { recursive: true, mode: 0o700 });
61
+ const authorityPath = (kind, key) => join(root, `${createHash("sha256").update(`${kind}\0${key}`).digest("hex")}.lock`);
62
+ const locationKey = (path) => `${realpathSync.native(dirname(path))}\0${process.platform === "win32" ? basename(path).toLowerCase() : basename(path)}`;
63
+ const identityKey = (path) => {
64
+ const physical = realpathSync.native(path);
65
+ const metadata = statSync(physical, { bigint: true });
66
+ return `${metadata.dev}:${metadata.ino}`;
67
+ };
68
+ const acquireAuthority = (path) => {
69
+ for (let attempt = 0; attempt < 2; attempt += 1) {
70
+ try {
71
+ const descriptor = openSync(path, "wx", 0o600);
72
+ writeFileSync(descriptor, JSON.stringify({ pid: process.pid, kind: process.env.A1_TAB_ID ? "resident tab" : "another A1 process" }));
73
+ closeSync(descriptor);
74
+ return;
75
+ }
76
+ catch (error) {
77
+ if (attempt === 0) {
78
+ try {
79
+ const record = JSON.parse(readFileSync(path, "utf8"));
80
+ if (typeof record.pid === "number" && !processIsLive(record.pid)) {
81
+ rmSync(path, { force: true });
82
+ continue;
83
+ }
84
+ }
85
+ catch {
86
+ // Security: malformed or racing lock evidence remains authoritative and fails closed.
87
+ }
88
+ }
89
+ throw error;
90
+ }
91
+ }
92
+ };
93
+ return {
94
+ acquire(requested) {
95
+ const absolute = resolve(requested);
96
+ const location = authorityPath("location", locationKey(absolute));
97
+ acquireAuthority(location);
98
+ let identity;
99
+ let identityAcquired = false;
100
+ let bound = false;
101
+ try {
102
+ if (existsSync(absolute)) {
103
+ const key = identityKey(absolute);
104
+ identity = authorityPath("identity", key);
105
+ acquireAuthority(identity);
106
+ identityAcquired = true;
107
+ if (identityKey(absolute) !== key) {
108
+ throw new Error("session identity changed while its writer lock was acquired");
109
+ }
110
+ rmSync(location, { force: true });
111
+ bound = true;
112
+ }
113
+ }
114
+ catch (error) {
115
+ rmSync(location, { force: true });
116
+ if (identityAcquired && identity !== undefined)
117
+ rmSync(identity, { force: true });
118
+ throw error;
119
+ }
120
+ let released = false;
121
+ return {
122
+ get bound() { return bound; },
123
+ bindCreated(created) {
124
+ if (bound || resolve(created) !== absolute || !existsSync(absolute)) {
125
+ throw new Error("created session does not match its reservation");
126
+ }
127
+ const key = identityKey(absolute);
128
+ identity = authorityPath("identity", key);
129
+ acquireAuthority(identity);
130
+ if (identityKey(absolute) !== key) {
131
+ rmSync(identity, { force: true });
132
+ identity = undefined;
133
+ throw new Error("created session identity changed during bind");
134
+ }
135
+ rmSync(location, { force: true });
136
+ bound = true;
137
+ },
138
+ release() {
139
+ if (released)
140
+ throw new Error("session lock was already released");
141
+ released = true;
142
+ rmSync(bound ? identity : location, { force: true });
143
+ },
144
+ };
145
+ },
146
+ };
147
+ }
148
+ function backend() {
149
+ return backendOverride ?? (cachedBackend ??= loadNativeBackend() ?? portableBackend());
150
+ }
151
+ function acquire(path) {
152
+ const absolute = resolve(path);
153
+ let lock;
154
+ try {
155
+ lock = backend().acquire(absolute);
156
+ }
157
+ catch {
158
+ throw new SessionWriterConflict(absolute, process.env.A1_TAB_ID ? "a resident tab" : "another A1 process");
159
+ }
160
+ let released = false;
161
+ return {
162
+ path: absolute,
163
+ get bound() { return lock.bound; },
164
+ bind(createdPath = absolute) {
165
+ if (released)
166
+ throw new Error("session writer lock was released");
167
+ if (!lock.bound)
168
+ lock.bindCreated(resolve(createdPath));
169
+ },
170
+ release() {
171
+ if (released)
172
+ return;
173
+ released = true;
174
+ lock.release();
175
+ },
176
+ };
177
+ }
178
+ export function acquireExisting(path) {
179
+ if (!existsSync(path))
180
+ throw new Error(`session file does not exist: ${path}`);
181
+ return acquire(path);
182
+ }
183
+ export function reserveNew(parent, name) {
184
+ if (!name || basename(name) !== name)
185
+ throw new Error("session reservation requires one file name");
186
+ return acquire(join(parent, name));
187
+ }
188
+ export function acquireSessionWriter(path) {
189
+ return acquire(path);
190
+ }
191
+ export function bind(handle, createdPath) {
192
+ handle.bind(createdPath);
193
+ }
194
+ export function release(handle) {
195
+ handle.release();
196
+ }
197
+ /** Test-only backend seam; passing undefined restores native discovery. */
198
+ export function setSessionWriterLockBackendForTest(value) {
199
+ backendOverride = value;
200
+ cachedBackend = undefined;
201
+ }
@@ -10,7 +10,7 @@ export const STARTUP_DESCRIPTOR = Object.freeze({
10
10
  ],
11
11
  "generatedArtifact": {
12
12
  "path": "dist/integrations/pi/startup-public.js",
13
- "sha256": "62906f5056fabed7a83b97843e3a407c955103ab2bb7849e6713026fe7c760a9"
13
+ "sha256": "2e5c23263868c689b0b76648a7565fe4384f8144f4c11b64569a08fc4d3502c2"
14
14
  },
15
15
  "dependencyLayerIdentity": {
16
16
  "source": "A1_RELEASE_LAYERS",
@@ -19,7 +19,7 @@ export const STARTUP_DESCRIPTOR = Object.freeze({
19
19
  "compileCacheNamespace": {
20
20
  "strategy": "node-abi-version-and-ordered-layer-sha256-v1"
21
21
  },
22
- "identity": "089bcfdc784e7d61cd028ede3b5546864ab49e6329e1296ed55afacb16bcb077"
22
+ "identity": "5d1fea810b3c76b1560dd3a743dd4db0b8d03935d9f5079fd4b2da55d4f1084a"
23
23
  });
24
24
 
25
25
  export function loadDeclaredStartupGraph() {
@@ -1,3 +1,3 @@
1
- export { EMERGENCY_TERMINAL_RESET, boundedCleanup, restoreAfterOwnedExit, restoreProcessTerminal } from "./terminal-reset.js";
1
+ export { CLEAR_EXIT_INTERVAL_MS, EMERGENCY_TERMINAL_RESET, boundedCleanup, restoreAfterOwnedExit, restoreProcessTerminal } from "./terminal-reset.js";
2
2
  export { installFatalExit, writeFatalDiagnostic } from "./fatal-exit.js";
3
3
  export type { FatalExitOptions } from "./fatal-exit.js";
@@ -1,2 +1,2 @@
1
- export { EMERGENCY_TERMINAL_RESET, boundedCleanup, restoreAfterOwnedExit, restoreProcessTerminal } from "./terminal-reset.js";
1
+ export { CLEAR_EXIT_INTERVAL_MS, EMERGENCY_TERMINAL_RESET, boundedCleanup, restoreAfterOwnedExit, restoreProcessTerminal } from "./terminal-reset.js";
2
2
  export { installFatalExit, writeFatalDiagnostic } from "./fatal-exit.js";
@@ -1,3 +1,4 @@
1
+ export declare const CLEAR_EXIT_INTERVAL_MS = 500;
1
2
  export declare const EMERGENCY_TERMINAL_RESET: string;
2
3
  export declare function restoreProcessTerminal(): void;
3
4
  export declare function restoreAfterOwnedExit(ownsTerminal: boolean, code: number | null, signal: string | null, restore?: () => void): number;
@@ -1,4 +1,5 @@
1
1
  import { writeSync } from "node:fs";
2
+ export const CLEAR_EXIT_INTERVAL_MS = 500;
2
3
  // Protocol: reset modes on both screens; setting keyboard flags to zero is idempotent,
3
4
  // unlike repeatedly popping a keyboard-protocol stack owned by a parent application.
4
5
  // Resetting parent-screen margins homes the cursor, so preserve its restored position.
@@ -44,7 +44,7 @@ export declare class OwnedEditorUxInterception {
44
44
  pasteClipboard(): boolean;
45
45
  }
46
46
  export interface PromptSelectionUxOptions {
47
- readonly copyText: (text: string) => void;
47
+ readonly copyText: (text: string, cut: boolean) => void;
48
48
  readonly readClipboardContent: () => Promise<PiShellClipboardContent | null>;
49
49
  readonly beginClipboardPaste?: () => PiShellPasteReservation;
50
50
  readonly beginTextPaste?: (text: string) => PiShellPasteReservation;
@@ -88,12 +88,12 @@ class PromptSelectionInterceptor {
88
88
  return;
89
89
  }
90
90
  if (this.keybindings.matches(data, "tui.input.copy") && this.hasSelection()) {
91
- this.options.copyText(this.options.expandCopiedText(this.#selectedText()));
91
+ this.options.copyText(this.options.expandCopiedText(this.#selectedText()), false);
92
92
  this.#collapseCopiedSelection();
93
93
  return;
94
94
  }
95
95
  if (this.keybindings.matches(data, "owned.editor.cut") && this.hasSelection()) {
96
- this.options.copyText(this.options.expandCopiedText(this.#selectedText()));
96
+ this.options.copyText(this.options.expandCopiedText(this.#selectedText()), true);
97
97
  if (!this.#deleteSelection())
98
98
  this.#deleteAtomicFocus();
99
99
  return;
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Attributed owned theme resources adapted from @earendil-works/pi-coding-agent 1.1.0 (MIT),
3
- * commit abe508e1b89912adde45528136c3221eb69acdd7.
4
- * Upstream dark.json SHA-256: c11a588b714d35300293079b425fb09a3693d4b2d453585d211b08163c648b75
5
- * Upstream light.json SHA-256: f590c51c2bc8b238891efd0e983473ed2e2a6487b6692cc1d4b2845165e703f7
2
+ * Attributed owned theme resources adapted from @earendil-works/pi-coding-agent 1.2.0 (MIT),
3
+ * commit 06a466935536f8c9bcacb2d5efc0fc021be1bdff.
4
+ * Upstream dark.json SHA-256: e1f96982f8cb7d2a48eca7db03c9cb282cb1e14a243680cd855638ecd6a251b6
5
+ * Upstream light.json SHA-256: 2dee6a4be7f765e7fd7728166b7ebf8c29e4ce313f8ec6b38ae50699e3abc2f3
6
6
  * Modifications: removed upstream schema/export metadata; runtime color data is unchanged.
7
7
  */
8
8
  export declare const BUILTIN_THEME_RESOURCES: Readonly<{
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Attributed owned theme resources adapted from @earendil-works/pi-coding-agent 1.1.0 (MIT),
3
- * commit abe508e1b89912adde45528136c3221eb69acdd7.
4
- * Upstream dark.json SHA-256: c11a588b714d35300293079b425fb09a3693d4b2d453585d211b08163c648b75
5
- * Upstream light.json SHA-256: f590c51c2bc8b238891efd0e983473ed2e2a6487b6692cc1d4b2845165e703f7
2
+ * Attributed owned theme resources adapted from @earendil-works/pi-coding-agent 1.2.0 (MIT),
3
+ * commit 06a466935536f8c9bcacb2d5efc0fc021be1bdff.
4
+ * Upstream dark.json SHA-256: e1f96982f8cb7d2a48eca7db03c9cb282cb1e14a243680cd855638ecd6a251b6
5
+ * Upstream light.json SHA-256: 2dee6a4be7f765e7fd7728166b7ebf8c29e4ce313f8ec6b38ae50699e3abc2f3
6
6
  * Modifications: removed upstream schema/export metadata; runtime color data is unchanged.
7
7
  */
8
8
  export const BUILTIN_THEME_RESOURCES = Object.freeze({
@@ -6,7 +6,7 @@ import { hotkeysMarkdown } from "./shell-presenters-info.js";
6
6
  export function renderPiShellHotkeySections(presentation, width) {
7
7
  ensureTheme();
8
8
  const shortcuts = presentation.getShortcuts ?? (() => []);
9
- const markdown = hotkeysMarkdown(presentation.bindings, shortcuts, presentation.profile ?? "pi");
9
+ const markdown = hotkeysMarkdown(presentation.bindings, shortcuts, presentation.profile ?? "pi", presentation.residentTabs);
10
10
  const sections = [];
11
11
  for (const line of markdown.split("\n")) {
12
12
  const heading = /^\*\*(.+)\*\*$/.exec(line)?.[1];
@@ -68,11 +68,13 @@ export interface PiShellHotkeysPresentation {
68
68
  readonly bindings?: KeybindingsConfig;
69
69
  readonly getShortcuts?: NonNullable<PiShellExtensionRendererResolver["getShortcuts"]>;
70
70
  readonly profile?: "pi" | "a1";
71
+ readonly residentTabs?: boolean;
71
72
  }
72
- export declare function createPiShellHotkeys(bindings?: KeybindingsConfig, getShortcuts?: NonNullable<PiShellExtensionRendererResolver["getShortcuts"]>, profile?: "pi" | "a1"): PiShellComponentPort;
73
+ export declare function createPiShellHotkeys(bindings?: KeybindingsConfig, getShortcuts?: NonNullable<PiShellExtensionRendererResolver["getShortcuts"]>, profile?: "pi" | "a1", residentTabs?: boolean): PiShellComponentPort;
73
74
  /** The keyboard-shortcut document rows the feed presenter shows, without its spacer, borders, and heading. */
74
75
  export declare function renderPiShellHotkeysLines(presentation: PiShellHotkeysPresentation, width: number): readonly string[];
75
- export declare function hotkeysMarkdown(bindings: KeybindingsConfig | undefined, getShortcuts: NonNullable<PiShellExtensionRendererResolver["getShortcuts"]>, profile: "pi" | "a1"): string;
76
+ export declare const TAB_HOTKEYS: readonly (readonly [string, string | null, string])[];
77
+ export declare function hotkeysMarkdown(bindings: KeybindingsConfig | undefined, getShortcuts: NonNullable<PiShellExtensionRendererResolver["getShortcuts"]>, profile: "pi" | "a1", residentTabs?: boolean): string;
76
78
  /**
77
79
  * Pinned Pi's `showPackageUpdateNotification` banner: warning-coloured dynamic
78
80
  * borders around a bold warning title, the muted update instruction with the
@@ -147,9 +147,9 @@ function shortcutDisplay(key) {
147
147
  return label.charAt(0).toUpperCase() + label.slice(1);
148
148
  }).join("+")).join("/");
149
149
  }
150
- export function createPiShellHotkeys(bindings, getShortcuts = () => [], profile = "pi") {
150
+ export function createPiShellHotkeys(bindings, getShortcuts = () => [], profile = "pi", residentTabs = false) {
151
151
  ensureTheme();
152
- const markdown = hotkeysMarkdown(bindings, getShortcuts, profile);
152
+ const markdown = hotkeysMarkdown(bindings, getShortcuts, profile, residentTabs);
153
153
  const container = new Container();
154
154
  container.addChild(new Spacer(1));
155
155
  container.addChild(new DynamicBorder(paintPiBorder));
@@ -162,12 +162,20 @@ export function createPiShellHotkeys(bindings, getShortcuts = () => [], profile
162
162
  /** The keyboard-shortcut document rows the feed presenter shows, without its spacer, borders, and heading. */
163
163
  export function renderPiShellHotkeysLines(presentation, width) {
164
164
  ensureTheme();
165
- return hotkeysMarkdownComponent(hotkeysMarkdown(presentation.bindings, presentation.getShortcuts ?? (() => []), presentation.profile ?? "pi")).render(width);
165
+ return hotkeysMarkdownComponent(hotkeysMarkdown(presentation.bindings, presentation.getShortcuts ?? (() => []), presentation.profile ?? "pi", presentation.residentTabs)).render(width);
166
166
  }
167
167
  function hotkeysMarkdownComponent(markdown) {
168
168
  return new Markdown(markdown, 1, 1, getPiHotkeysMarkdownTheme());
169
169
  }
170
- export function hotkeysMarkdown(bindings, getShortcuts, profile) {
170
+ // Performance: keep startup presentation independent from the registry; parity is contract-tested.
171
+ export const TAB_HOTKEYS = [
172
+ ["tabs.new", "alt+a", "New A1 tab"], ["tabs.close", "alt+w", "Close A1 tab"],
173
+ ["tabs.rename", "f2", "Rename A1 tab"],
174
+ ...Array.from({ length: 10 }, (_, index) => [`tabs.jump${index + 1}`, `alt+${(index + 1) % 10}`, `View A1 tab ${index + 1}`]),
175
+ ["tabs.next", null, "View next A1 tab"], ["tabs.previous", null, "View previous A1 tab"],
176
+ ["tabs.moveRight", null, "Move A1 tab right"], ["tabs.moveLeft", null, "Move A1 tab left"],
177
+ ];
178
+ export function hotkeysMarkdown(bindings, getShortcuts, profile, residentTabs = false) {
171
179
  const keys = profile === "a1" ? KeybindingsManager.fromOwnedBindings(bindings) : new KeybindingsManager(bindings);
172
180
  // Compatibility: the owned viewport consumes these physical chords before editor actions.
173
181
  const display = (action) => keys.getKeys(action)
@@ -180,6 +188,32 @@ export function hotkeysMarkdown(bindings, getShortcuts, profile) {
180
188
  : `\`${label}\``;
181
189
  }).join(" / ")} | ${description} |`;
182
190
  let markdown = ["**Navigation**", "| Key | Action |", "|-----|--------|", row(["tui.editor.cursorUp", "tui.editor.cursorDown", "tui.editor.cursorLeft", "tui.editor.cursorRight"], "Move cursor / browse history"), row(["tui.editor.cursorWordLeft", "tui.editor.cursorWordRight"], "Move by word"), row(["tui.editor.cursorLineStart"], profile === "a1" ? "Start of prompt line" : "Start of line"), row(["tui.editor.cursorLineEnd"], profile === "a1" ? "End of prompt line" : "End of line"), ...(profile === "a1" ? ["| `Ctrl+Home` | Start of content |", "| `Ctrl+End` | End of content / follow output |"] : []), row(["tui.editor.jumpForward"], "Jump forward to character"), row(["tui.editor.jumpBackward"], "Jump backward to character"), row(["tui.editor.pageUp", "tui.editor.pageDown"], "Scroll by page"), "", "**Editing**", "| Key | Action |", "|-----|--------|", row(["tui.input.submit"], "Send message"), row(["tui.input.newLine"], `New line${process.platform === "win32" ? " (Ctrl+Enter on Windows Terminal)" : ""}`), row(["tui.editor.deleteWordBackward"], "Delete word backwards"), row(["tui.editor.deleteWordForward"], "Delete word forwards"), row(["tui.editor.deleteToLineStart"], "Delete to start of line"), row(["tui.editor.deleteToLineEnd"], "Delete to end of line"), row(["tui.editor.yank"], "Paste the most-recently-deleted text"), row(["tui.editor.yankPop"], "Cycle through the deleted text after pasting"), row(["tui.editor.undo"], "Undo"), "", "**Other**", "| Key | Action |", "|-----|--------|", row(["tui.input.tab"], "Path completion / accept autocomplete"), row(["app.interrupt"], "Cancel autocomplete / abort streaming"), row(["app.clear"], "Clear editor (first) / exit (second)"), row(["app.exit"], "Exit (when editor is empty)"), row(["app.suspend"], "Suspend to background"), row(["app.thinking.cycle"], "Cycle thinking level"), row(["app.model.cycleForward", "app.model.cycleBackward"], "Cycle models"), row(["app.model.select"], profile === "a1" ? "Open the Models dialog" : "Open model selector"), row(["app.tools.expand"], "Toggle tool output expansion"), row(["app.thinking.toggle"], "Toggle thinking block visibility"), row(["app.editor.external"], "Edit message in external editor"), row(["app.message.copy"], "Copy selection or last assistant message"), row(["app.message.followUp"], "Queue follow-up message"), row(["app.message.dequeue"], "Restore queued messages"), row(["app.clipboard.pasteImage"], profile === "a1" ? "Paste image or text from clipboard" : "Paste files on macOS, images, or text from clipboard"), "| `/` | Slash commands |", "| `!` | Run bash command |", "| `!!` | Run bash command (excluded from context) |", ...(profile === "a1" ? ["", "**Models dialog**", "| Key | Action |", "|-----|--------|", "| `Space` | Toggle the selected model in the cycling scope |", "| `Tab` | Switch the all/scoped filter |", row(["app.models.save"], "Save the scope to settings"), row(["app.models.enableAll"], "Scope every listed model"), row(["app.models.clearAll"], "Clear the listed models from the scope"), row(["app.models.toggleProvider"], "Toggle the selected model's provider"), row(["app.models.reorderUp", "app.models.reorderDown"], "Reorder the cycling scope")] : [])].join("\n");
191
+ if (profile === "a1" && residentTabs) {
192
+ const configured = (bindings ?? {});
193
+ markdown += "\n\n**Tabs**\n| Key | Action |\n|-----|--------|\n";
194
+ const claimed = new Set();
195
+ for (const [action, value] of Object.entries(configured)) {
196
+ if (action.startsWith("tabs."))
197
+ continue;
198
+ const keys = typeof value === "string" ? [value] : Array.isArray(value) ? value : [];
199
+ for (const key of keys)
200
+ if (typeof key === "string")
201
+ claimed.add(key.toLowerCase());
202
+ }
203
+ markdown += TAB_HOTKEYS.map(([id, defaultKey, description]) => {
204
+ const value = configured[id];
205
+ const assigned = (typeof value === "string" ? [value] : Array.isArray(value) ? value.filter((key) => typeof key === "string") : defaultKey === null ? [] : [defaultKey])
206
+ .filter(key => {
207
+ const normalized = key.toLowerCase();
208
+ if (claimed.has(normalized))
209
+ return false;
210
+ claimed.add(normalized);
211
+ return true;
212
+ });
213
+ const label = assigned.length === 0 ? "Unbound" : `\`${assigned.map(shortcutDisplay).join("/")}\``;
214
+ return `| ${label} | ${description} |`;
215
+ }).join("\n");
216
+ }
183
217
  const shortcuts = getShortcuts(bindings ?? keys.getEffectiveConfig());
184
218
  if (shortcuts.length > 0) {
185
219
  markdown += "\n\n**Extensions**\n| Key | Action |\n|-----|--------|\n";
@@ -185,7 +185,7 @@ export interface PiShellEditorOptions {
185
185
  readonly onFollowUp?: (() => void) | undefined;
186
186
  readonly onDequeue?: (() => void) | undefined;
187
187
  readonly onPromptSuggestionAccepted?: (text: string) => void;
188
- readonly onCopyText?: (text: string) => void;
188
+ readonly onCopyText?: (text: string, cut: boolean) => void;
189
189
  readonly readClipboardContent?: (signal?: AbortSignal) => Promise<PiShellClipboardContent | null>;
190
190
  readonly beginClipboardPaste?: () => PiShellPasteReservation;
191
191
  readonly beginTextPaste?: (text: string) => PiShellPasteReservation;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.1.0 (MIT), commit abe508e1b89912adde45528136c3221eb69acdd7,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.2.0 (MIT), commit 06a466935536f8c9bcacb2d5efc0fc021be1bdff,
3
3
  * packages/coding-agent/src/core/keybindings.ts.
4
4
  * Modifications: Mechanical source port with Node import prefixes, public package-root agent-directory
5
5
  * resolution, and an opt-in bare-A1 input profile including Ctrl+L level cycling, unbound model
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.1.0 (MIT), commit abe508e1b89912adde45528136c3221eb69acdd7,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.2.0 (MIT), commit 06a466935536f8c9bcacb2d5efc0fc021be1bdff,
3
3
  * packages/coding-agent/src/core/keybindings.ts.
4
4
  * Modifications: Mechanical source port with Node import prefixes, public package-root agent-directory
5
5
  * resolution, and an opt-in bare-A1 input profile including Ctrl+L level cycling, unbound model
@@ -9,7 +9,7 @@
9
9
  * Deviations: keybindings-public-config-boundary, owned-level-cycle-shortcut,
10
10
  * owned-input-keybinding-aliases, owned-session-tree-dialog, owned-dialog-ctrl-c-cancel.
11
11
  */
12
- import { matchesKey, TUI_KEYBINDINGS, KeybindingsManager as TuiKeybindingsManager, } from "@earendil-works/pi-tui";
12
+ import { Key, matchesKey, TUI_KEYBINDINGS, KeybindingsManager as TuiKeybindingsManager, } from "@earendil-works/pi-tui";
13
13
  import { existsSync, readFileSync } from "node:fs";
14
14
  import { join } from "node:path";
15
15
  import { getAgentDir } from "../../../../startup-public.js";
@@ -278,14 +278,27 @@ const KEYBINDING_NAME_MIGRATIONS = {
278
278
  function isLegacyKeybindingName(key) {
279
279
  return key in KEYBINDING_NAME_MIGRATIONS;
280
280
  }
281
+ const KEYBINDING_MODIFIERS = ["ctrl", "shift", "alt", "super"];
282
+ const BASE_KEY_PATTERN = `(?:[a-z0-9]|${Object.values(Key)
283
+ .flatMap((value) => (typeof value === "string" ? [value.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&")] : []))
284
+ .join("|")})`;
285
+ const DUPLICATE_MODIFIER_PATTERN = KEYBINDING_MODIFIERS
286
+ .map((modifier) => `${modifier}\\+.*${modifier}\\+`)
287
+ .join("|");
288
+ const KEY_ID_PATTERN = new RegExp(`^(?!.*(?:${DUPLICATE_MODIFIER_PATTERN}))(?:(?:${KEYBINDING_MODIFIERS.join("|")})\\+){0,4}${BASE_KEY_PATTERN}$`);
289
+ function isKeyId(value) {
290
+ return typeof value === "string" && KEY_ID_PATTERN.test(value);
291
+ }
281
292
  function toKeybindingsConfig(value) {
282
293
  const config = {};
283
294
  for (const [key, binding] of Object.entries(value)) {
284
- if (typeof binding === "string") {
295
+ if (key === "$schema")
296
+ continue;
297
+ if (isKeyId(binding)) {
285
298
  config[key] = binding;
286
299
  continue;
287
300
  }
288
- if (Array.isArray(binding) && binding.every((entry) => typeof entry === "string")) {
301
+ if (Array.isArray(binding) && binding.every(isKeyId)) {
289
302
  config[key] = binding;
290
303
  }
291
304
  }
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "sourcePackage": "@earendil-works/pi-coding-agent",
3
- "sourceVersion": "1.1.0",
3
+ "sourceVersion": "1.2.0",
4
4
  "upstreamRepository": "https://github.com/earendil-works/pi.git",
5
- "upstreamCommit": "abe508e1b89912adde45528136c3221eb69acdd7",
5
+ "upstreamCommit": "06a466935536f8c9bcacb2d5efc0fc021be1bdff",
6
6
  "sourcePath": "dist/modes/interactive/assets/clankolas.png",
7
7
  "sourceSha256": "169acd0dfe6fbb8d8742ed24a3fc654fd0b2e2d4223c733249c5493723f1b72d",
8
8
  "license": "MIT",
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.1.0 (MIT), commit abe508e1b89912adde45528136c3221eb69acdd7,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.2.0 (MIT), commit 06a466935536f8c9bcacb2d5efc0fc021be1bdff,
3
3
  * packages/coding-agent/src/modes/interactive/components/countdown-timer.ts.
4
4
  * Modifications: Mechanical source port with ECMAScript private fields; imports remain on the public
5
5
  * Pi TUI package root.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.1.0 (MIT), commit abe508e1b89912adde45528136c3221eb69acdd7,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.2.0 (MIT), commit 06a466935536f8c9bcacb2d5efc0fc021be1bdff,
3
3
  * packages/coding-agent/src/modes/interactive/components/earendil-announcement.ts.
4
4
  * Modifications: Mechanical pinned source port with private imports remapped to public package-root
5
5
  * types/APIs and A1-owned theme boundaries. The unchanged image is loaded lazily from its attributed,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.1.0 (MIT), commit abe508e1b89912adde45528136c3221eb69acdd7,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.2.0 (MIT), commit 06a466935536f8c9bcacb2d5efc0fc021be1bdff,
3
3
  * packages/coding-agent/src/modes/interactive/components/extension-editor.ts.
4
4
  * Modifications: Mechanical port: remap pi-tui to the root public singleton, use owned
5
5
  * keybindings/theme and external-editor seams, preserve editor layout, hints, focus, submission,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.1.0 (MIT), commit abe508e1b89912adde45528136c3221eb69acdd7,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.2.0 (MIT), commit 06a466935536f8c9bcacb2d5efc0fc021be1bdff,
3
3
  * packages/coding-agent/src/modes/interactive/components/extension-editor.ts.
4
4
  * Modifications: Mechanical port: remap pi-tui to the root public singleton, use owned
5
5
  * keybindings/theme and external-editor seams, preserve editor layout, hints, focus, submission,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.1.0 (MIT), commit abe508e1b89912adde45528136c3221eb69acdd7,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.2.0 (MIT), commit 06a466935536f8c9bcacb2d5efc0fc021be1bdff,
3
3
  * packages/coding-agent/src/modes/interactive/components/extension-input.ts.
4
4
  * Modifications: Mechanical port: remap public imports, use ECMAScript private fields, and route the
5
5
  * bare-A1 instruction row and chrome through the shared semantic shortcut and compact padded
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.1.0 (MIT), commit abe508e1b89912adde45528136c3221eb69acdd7,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.2.0 (MIT), commit 06a466935536f8c9bcacb2d5efc0fc021be1bdff,
3
3
  * packages/coding-agent/src/modes/interactive/components/extension-selector.ts.
4
4
  * Modifications: Mechanical port: remap public imports, use ECMAScript private fields, and route the
5
5
  * bare-A1 instruction row and chrome through the shared semantic shortcut and compact padded
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.1.0 (MIT), commit abe508e1b89912adde45528136c3221eb69acdd7,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.2.0 (MIT), commit 06a466935536f8c9bcacb2d5efc0fc021be1bdff,
3
3
  * packages/coding-agent/src/modes/interactive/components/mermaid.ts.
4
4
  * Modifications: Mechanical pinned source port with private imports remapped to public package-root
5
5
  * types/APIs and A1-owned theme boundaries; behavior remains acceptance-tested.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.1.0 (MIT), commit abe508e1b89912adde45528136c3221eb69acdd7,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.2.0 (MIT), commit 06a466935536f8c9bcacb2d5efc0fc021be1bdff,
3
3
  * packages/coding-agent/src/modes/interactive/components/custom-editor.ts.
4
4
  * Modifications: A1-owned class name and synchronized A1 keybinding contract replace the nominal
5
5
  * private upstream keybinding constructor dependency; bare A1 injects the shared Settings/agent input
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.1.0 (MIT), commit abe508e1b89912adde45528136c3221eb69acdd7,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.2.0 (MIT), commit 06a466935536f8c9bcacb2d5efc0fc021be1bdff,
3
3
  * packages/coding-agent/src/modes/interactive/components/custom-editor.ts.
4
4
  * Modifications: A1-owned class name and synchronized A1 keybinding contract replace the nominal
5
5
  * private upstream keybinding constructor dependency; bare A1 injects the shared Settings/agent input
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.1.0 (MIT), commit abe508e1b89912adde45528136c3221eb69acdd7,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.2.0 (MIT), commit 06a466935536f8c9bcacb2d5efc0fc021be1bdff,
3
3
  * packages/coding-agent/src/modes/interactive/components/pi-logo.ts.
4
4
  * Modifications: Remapped the private theme import to A1's public-backed adapter and composed the
5
5
  * fixed-color logo into the owned startup header.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.1.0 (MIT), commit abe508e1b89912adde45528136c3221eb69acdd7,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.2.0 (MIT), commit 06a466935536f8c9bcacb2d5efc0fc021be1bdff,
3
3
  * packages/coding-agent/src/modes/interactive/components/scoped-models-selector.ts.
4
4
  * Modifications: Source-synchronized scoped-model selector port: preserve session-only toggles,
5
5
  * search, bulk/provider/reorder actions, dirty state, Ctrl+S persistence, refresh status,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.1.0 (MIT), commit abe508e1b89912adde45528136c3221eb69acdd7,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.2.0 (MIT), commit 06a466935536f8c9bcacb2d5efc0fc021be1bdff,
3
3
  * packages/coding-agent/src/modes/interactive/components/footer.ts.
4
4
  * Modifications: Consumes neutral owned-UI view data instead of a fabricated concrete AgentSession;
5
5
  * preserves the latest physical route for virtual models; an explicit bare-A1 profile colors the
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.1.0 (MIT), commit abe508e1b89912adde45528136c3221eb69acdd7,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.2.0 (MIT), commit 06a466935536f8c9bcacb2d5efc0fc021be1bdff,
3
3
  * packages/coding-agent/src/modes/interactive/components/session-selector-search.ts.
4
4
  * Modifications: Source-synchronized session search port with only the public SessionInfo type import
5
5
  * remapped.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.1.0 (MIT), commit abe508e1b89912adde45528136c3221eb69acdd7,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.2.0 (MIT), commit 06a466935536f8c9bcacb2d5efc0fc021be1bdff,
3
3
  * packages/coding-agent/src/modes/interactive/components/session-selector.ts.
4
4
  * Modifications: Source-synchronized session selector port: preserve threaded/current/all scope,
5
5
  * search, sort, named/path filters, rename, delete confirmation, active-session protection,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.1.0 (MIT), commit abe508e1b89912adde45528136c3221eb69acdd7,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.2.0 (MIT), commit 06a466935536f8c9bcacb2d5efc0fc021be1bdff,
3
3
  * packages/coding-agent/src/modes/interactive/components/skill-invocation-message.ts.
4
4
  * Modifications: Mechanical port uses A1's public pi-tui instance, owned theme boundary, and
5
5
  * root-instance keybinding registry because the public coding-agent component closes over a second
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.1.0 (MIT), commit abe508e1b89912adde45528136c3221eb69acdd7,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.2.0 (MIT), commit 06a466935536f8c9bcacb2d5efc0fc021be1bdff,
3
3
  * packages/coding-agent/src/modes/interactive/components/skill-invocation-message.ts.
4
4
  * Modifications: Mechanical port uses A1's public pi-tui instance, owned theme boundary, and
5
5
  * root-instance keybinding registry because the public coding-agent component closes over a second