@narumitw/pi-sync 0.57.8 → 0.57.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (21) hide show
  1. package/CHANGELOG.md +298 -0
  2. package/dist/chunks/{agent-refusal-retry-AH7TXOQT.ts → agent-refusal-retry-RPTMUQXK.ts} +2 -2
  3. package/dist/chunks/{chunk-N5TFMPB5.ts → chunk-6FVVRTL5.ts} +2 -2
  4. package/dist/chunks/{chunk-5XZOC7FD.ts → chunk-KHBPED6W.ts} +4 -1
  5. package/dist/chunks/chunk-KHBPED6W.ts.map +7 -0
  6. package/dist/chunks/{chunk-WD6FJHCK.ts → chunk-MKKF4IMY.ts} +2 -2
  7. package/dist/chunks/{conflict-review-UC5AGVER.ts → conflict-review-3X37QEIT.ts} +3 -3
  8. package/dist/chunks/{continuous-sync-POEQXR25.ts → continuous-sync-Q6QUD6TY.ts} +2 -2
  9. package/dist/chunks/{manager-ui-26LEINEX.ts → manager-ui-ZH6DEC2G.ts} +2 -2
  10. package/dist/chunks/{sync-operations-ZHA6HQDB.ts → sync-operations-Y72GNIQ2.ts} +3 -3
  11. package/dist/index.ts +5 -5
  12. package/package.json +5 -4
  13. package/src/ui/sync-confirmation.ts +3 -0
  14. package/dist/chunks/chunk-5XZOC7FD.ts.map +0 -7
  15. /package/dist/chunks/{agent-refusal-retry-AH7TXOQT.ts.map → agent-refusal-retry-RPTMUQXK.ts.map} +0 -0
  16. /package/dist/chunks/{chunk-N5TFMPB5.ts.map → chunk-6FVVRTL5.ts.map} +0 -0
  17. /package/dist/chunks/{chunk-WD6FJHCK.ts.map → chunk-MKKF4IMY.ts.map} +0 -0
  18. /package/dist/chunks/{conflict-review-UC5AGVER.ts.map → conflict-review-3X37QEIT.ts.map} +0 -0
  19. /package/dist/chunks/{continuous-sync-POEQXR25.ts.map → continuous-sync-Q6QUD6TY.ts.map} +0 -0
  20. /package/dist/chunks/{manager-ui-26LEINEX.ts.map → manager-ui-ZH6DEC2G.ts.map} +0 -0
  21. /package/dist/chunks/{sync-operations-ZHA6HQDB.ts.map → sync-operations-Y72GNIQ2.ts.map} +0 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,298 @@
1
+ # @narumitw/pi-sync
2
+
3
+ ## 0.57.9
4
+
5
+ ### Patch Changes
6
+
7
+ - 54f2700: Preserve fullscreen viewport capture through custom list wrappers so default and configured paging keys reach the focused list. Keep native transcript search, unrelated overlays, free-text modes, paste, and hard cancellation unchanged. Filter Kit key hints according to each screen's capture policy.
8
+
9
+ Update Recall and File Context to the current Kit dependency range. The selected consumer releases require the fixed Kit patch through Changesets dependency-floor updates.
10
+ - e484010: Include the existing package-root CHANGELOG.md in extension tarballs so Pi can show native update notices. Keep Changesets version headings and Pi's first-observation and collapseChangelog behavior unchanged.
11
+ - Updated dependencies [54f2700]
12
+ - Updated dependencies [6c76ef1]
13
+ - @narumitw/pi-tui-kit@0.69.0
14
+
15
+ ## 0.57.8
16
+
17
+ ### Patch Changes
18
+
19
+ - 9d3e0d7: Unreference passive refresh, debounce, expiry, and background startup timers so they do not keep the host process alive when other work has stopped. Keep normal cancellation and resource cleanup unchanged.
20
+ - Updated dependencies [9d3e0d7]
21
+ - @narumitw/pi-tui-kit@0.68.1
22
+
23
+ ## 0.57.7
24
+
25
+ ### Patch Changes
26
+
27
+ - 3bf3525: Keep startup timing reports in the TUI transcript without adding model context, and report the initial Continuous sync cycle when debug is enabled. Preserve RPC notifications and suppress repeated or stale cycle reports.
28
+
29
+ ## 0.57.6
30
+
31
+ ### Patch Changes
32
+
33
+ - Updated dependencies [a21d39b]
34
+ - Updated dependencies [f68aa54]
35
+ - Updated dependencies [b062d21]
36
+ - @narumitw/pi-tui-kit@0.68.0
37
+
38
+ ## 0.57.5
39
+
40
+ ### Patch Changes
41
+
42
+ - Updated dependencies [57eeae7]
43
+ - @narumitw/pi-tui-kit@0.67.0
44
+
45
+ ## 0.57.4
46
+
47
+ ### Patch Changes
48
+
49
+ - 168248c: Reuse published TUI Kit frame metadata, masked input, configured-key syntax, and interaction ownership while retaining extension-owned settings and cancellation policy. Keep malformed Ticker key strings from suppressing valid reorder shortcuts, and drain Usage settings saves after cancellation.
50
+
51
+ ## 0.57.3
52
+
53
+ ### Patch Changes
54
+
55
+ - 11da747: Recover Continuous sync after proven pre-publication edit races and repaired content safety blocks. Avoid model requests when unsupported conflicts prevent an all-or-nothing transfer, and propagate resolver deadlines through validation and reservation work.
56
+
57
+ Add a separately confirmed manager action to retry a current cached model refusal without resetting automatic accounting. Preserve ordinary Sync now cache behavior and retain the previous refusal privately. Show read-only request allowance, accounting capacity, and category-specific recovery guidance.
58
+
59
+ ## 0.57.2
60
+
61
+ ### Patch Changes
62
+
63
+ - 9f80b89: Use native fake-cursor markers for masked credential input and normalize unusable render widths without changing secret editing, validation, cancellation, or storage policy.
64
+ - Updated dependencies [077137a]
65
+ - Updated dependencies [9f80b89]
66
+ - Updated dependencies [efc474c]
67
+ - @narumitw/pi-tui-kit@0.66.0
68
+
69
+ ## 0.57.1
70
+
71
+ ### Patch Changes
72
+
73
+ - a87a2ba: Keep the higher local or remote explicit npm package version when Agent mode merges settings, without a registry lookup. Preserve matching resource filters and one-sided package order or membership changes. Keep changed non-npm sources and conflicting package lists under atomic conflict handling. Preserve existing package-array bytes and use ancestor rules when SemVer precedence is equal. Keep accepted settings documents unchanged unless a package override is required.
74
+
75
+ ## 0.57.0
76
+
77
+ ### Minor Changes
78
+
79
+ - fa985f7: Add the manual-only `configure-pi-sync` skill for configuration questions and safe setup guidance without private settings reads, edits, or sync execution.
80
+ Bundle the authoritative settings reference with the skill and preserve existing settings documentation anchors.
81
+
82
+ ## 0.56.0
83
+
84
+ ### Minor Changes
85
+
86
+ - 713eed4: Add default-off experimental Continuous sync with separate consent, local scheduler ownership, automatic detection and recovery, durable request limits, and safe blocked-state reporting. Bind each background cycle to its inspected settings and selected model before transfer, disclosure, publication, and local apply. Show the saved On or Off state in Continuous sync notifications.
87
+
88
+ ## 0.55.0
89
+
90
+ ### Minor Changes
91
+
92
+ - 1e86ba9: Add default-off experimental Agent mode for autonomous text and atomic settings conflict resolution through an isolated, tool-free Pi SDK session. Revalidate candidates before conditional publication, retain journal recovery, and coordinate local resolver ownership across Pi processes. Require a Pi runtime that supplies the tested public SDK boundary.
93
+
94
+ ### Patch Changes
95
+
96
+ - e0028ea: Simplify internal settings saves, initial-sync routing, cancellation checkpoints, and object-store snapshot metadata without changing sync behavior.
97
+
98
+ ## 0.54.3
99
+
100
+ ### Patch Changes
101
+
102
+ - 2a9ad3a: Add opt-in startup timing notifications with the global `debug` boolean setting, including local initialization, background inspection, and automatic transfer stages.
103
+ - d02ca5f: Skip remote snapshot downloads and baseline rewrites for verified unchanged automatic transfers while retaining recovery and conservative fallbacks. Add aggregated transfer-stage durations and call counts to startup debug reports.
104
+ - 8ae9e62: Group Settings by task, retain cross-category search, and clarify setting scope, save results, and independent startup policies. Add manager status/difference actions and directional transfer counts with safe-default scrollable TUI Pull/Push reviews. Recheck reviewed local content and baselines, preserve protected sessions in preview counts, and clarify that remote removals do not erase retained history.
105
+
106
+ ## 0.54.2
107
+
108
+ ### Patch Changes
109
+
110
+ - 491fc28: Fix Windows EPERM errors when syncing snapshot backups and staged recovery files by opening regular files with write access for flushing.
111
+
112
+ ## 0.54.1
113
+
114
+ ### Patch Changes
115
+
116
+ - 2191720: Show clear local and remote change summaries with one explicit safe-default confirmation and optional read-only details. Keep remote snapshot publication separate from file changes and preserve cancellation and stale-state guards. On compact terminals, scroll the main summary before approval; resizing resets the review and the safe default.
117
+
118
+ ## 0.54.0
119
+
120
+ ### Minor Changes
121
+
122
+ - 80eef72: Flatten the sync manager: expose reviewed Pull, Push, History, and Diagnostics directly, move destination and catalog management into searchable Settings, and show conflict/access recovery only when applicable. Preserve existing commands, automation policies, and safety confirmations.
123
+
124
+ Require the TUI Kit patch that preserves Settings search and cursor across refreshes, including queries that match printable keybindings.
125
+
126
+ Preserve Settings search and cursor across successful refreshes in TUI Kit, and restore Settings and Choice queries as sanitized pasted content without dispatching printable keybindings.
127
+
128
+ ### Patch Changes
129
+
130
+ - e32bf5b: Keep History rollback cancellation reachable after snapshot selection and confirmation restore the normal editor. Release the temporary terminal listener when the operation settles or its owner closes, and preserve the existing non-cancellable commit boundary. Ignore Kitty key-release events before matching cancellation so releasing a key does not abort History. Preserve focused dialogs' key priorities, and distinguish aborted or stale rollback confirmations from explicit rejection before notifying.
131
+ - Updated dependencies [6a2f900]
132
+ - Updated dependencies [80eef72]
133
+ - @narumitw/pi-tui-kit@0.65.5
134
+
135
+ ## 0.53.1
136
+
137
+ ### Patch Changes
138
+
139
+ - fbb7757: Request identity representations for S3 reads so transfer compression does not weaken R2 JSON ETags and block safe conditional publication. Weak or missing ETags still fail closed. Reconcile inactive journals recorded with compression-weakened revisions only when the current strong ETag and exact pointer reproduce the recorded revision and local content and baseline are unchanged; this equivalence never authorizes publication or apply.
140
+
141
+ Show bounded, terminal-safe, credential-redacted failure details for interrupted merged transfers while preserving journals, backups, and existing recovery behavior.
142
+
143
+ ## 0.53.0
144
+
145
+ ### Minor Changes
146
+
147
+ - d22b0b1: Support automatic transfer for R2/S3 using verified ETag conditional publication. Verify conditional-write behavior with an isolated temporary object before publication, protect active-pointer and history writes against concurrent writers, and preserve unknown-outcome recovery for transport failures. Credentials now require delete access for probe cleanup; unsupported conditional writes fail closed.
148
+
149
+ ## 0.52.1
150
+
151
+ ### Patch Changes
152
+
153
+ - 1e2df4b: Prevent reviewed case-only renames from deadlocking on case-insensitive filesystems while retaining file mutation queue protection for both spellings.
154
+
155
+ ## 0.52.0
156
+
157
+ ### Minor Changes
158
+
159
+ - 69fafc0: Add opt-in conservative settings field merging with verified private ancestors and explicit machine-local field projection. Portable policies use settings version 4 and snapshot version 2 so older clients refuse them; policy changes require directional migration confirmation and do not erase remote history. Support portable snapshots across S3, WebDAV and Git, retain version-4 setup management, capture initial accepted ancestors, prune completed cache history, and preview effective local images. Preserve per-setup policy absence, require explicit empty-policy migration, recheck force-push policies after remote refresh, clear cancelled migration status, and allow validated settings deletion when no excluded field is present. Bind recovery journals to policy presence, refuse pull policy rewrites until the authoritative remote matches, and preserve unsafe ancestor records during pruning. Surface policy-only changes in inspection, reject portable snapshots that retain excluded root fields, and guard empty first-sync acceptance. Finish rollback publication and prune accepted ancestors after post-commit cancellation while retaining session ownership checks. Require managed settings for nonempty exclusions, authorize rollback against current-head policy, refuse mismatched historical rules, and validate recovery images with their recorded policy so reviewed force recovery remains available. Normalize accepted portable projections without rejecting valid noncanonical journal JSON, refuse lossy numeric field merges and projections, and bind directional local-field writes to reviewed preimages through transaction backup preparation.
160
+ - a2b1e22: Add all-or-nothing, file-level three-way merging for **Sync now** with an established baseline. Independent changes merge automatically; initial-source choices, true conflicts, legacy selection policies, and session-root changes still require review. Explicit push/pull remain directional, and existing automatic defaults are unchanged.
161
+
162
+ Add an opt-in automatic startup transfer at idle in TUI/RPC for conditional or lease-protected backends. Transfers protect the current session, revalidate local content and settings, and never reload resources automatically. Cancellation clears owned progress without publishing stale attention or affecting a replacement session.
163
+
164
+ Harden interrupted-transfer recovery with durable private backups and journals, guarded file installation, case-only replacement handling, and verified settings/root-transition evidence, including settings deletion and canonical tilde expansion. Reject unsafe target aliases and newer or ambiguous filesystem states; preserve evidence for manual review rather than blindly restoring older content. Completed journals resume cleanup without rolling back accepted files. Do not downgrade while recovery evidence is pending.
165
+
166
+ Preserve supported native POSIX filenames, escape path controls in review output, and index transaction planning and recovery checks to avoid repeated full scans.
167
+ - 07f98a4: Add opt-in bounded text merging, conservative validated same-session prefix reconciliation, and durable partial progress with private conflict artifacts and deferred whole-group review. Withheld local/remote versions and old accepted ancestors survive publication and restart; older readers refuse version-5 settings/version-3 partial snapshots. Preserve unmanaged collision barriers and loaded-session protection, stop automatic transfers at unresolved conflicts, defer conflict artifacts for transfer plans until after approved fresh review, and complete setup arguments for conflict review. Accept Pi's public session ID grammar, recover withheld equal deletions, index conflict grouping and bounded previews, and dispatch manager conflict-review decisions. Preserve main's portability and recovery safety contracts, authorize explicit manager roots, move large reviewed settings postimages into hash-pinned private sidecars, track crash-owned recovery staging, index whole-group resolution, and omit colliding paths from accepted ancestor caches. Finish reviewed multi-child/nested directory replacements in one pass with guarded retry, prevent automatic or unreviewed whole-direction acceptance from clearing unresolved conflicts, and index withheld snapshot assembly and carried ancestor membership. Bound cumulative text diff and hunk work across retries, revalidate no-transfer acceptance before evidence publication, and release only newly owned, unreferenced artifacts after failed attempts.
168
+
169
+ ## 0.51.1
170
+
171
+ ### Patch Changes
172
+
173
+ - 68c4b95: Update runtime dependencies and preserve Pi tool-context types through the LSP session lifecycle guard for compatibility with current Pi releases.
174
+
175
+ ## 0.51.0
176
+
177
+ ### Minor Changes
178
+
179
+ - bef29cf: Add a global Show status setting that can suppress pi-sync status text while preserving widgets and notifications.
180
+
181
+ ### Patch Changes
182
+
183
+ - ae48402: Replace verbose status messages with compact `sync ...`, `sync ⇡`, `sync ⇣`, and `sync ⇕` indicators.
184
+
185
+ ## 0.50.3
186
+
187
+ ### Patch Changes
188
+
189
+ - 7ec32e4: Reuse published Kit interaction hints for secret input and cancellable operations. Deduplicate cancel aliases and omit the submit hint when no submit key is configured.
190
+ - Updated dependencies [317f7bd]
191
+ - @narumitw/pi-tui-kit@0.61.0
192
+
193
+ ## 0.50.2
194
+
195
+ ### Patch Changes
196
+
197
+ - f6f26ff: Reserve persistent sync widgets and RPC warnings for review conditions. Show ordinary one-sided changes through status, keep setup and empty-remote initialization guidance in the manager, and preserve observations and transfer safety checks.
198
+
199
+ ## 0.50.1
200
+
201
+ ### Patch Changes
202
+
203
+ - 0f319d2: Add a themed horizontal separator above the sync attention widget to match other widgets above the editor.
204
+
205
+ ## 0.50.0
206
+
207
+ ### Minor Changes
208
+
209
+ - f566ede: Replace automatic startup transfers with a cancellable background check in TUI and RPC. Pi no longer waits for remote storage or opens startup conflict dialogs; review differences through `/sync` before transferring. The existing `sync.automatic` setting now checks only at startup, while its sessions-enabled automatic shutdown push remains unchanged. Print and JSON modes skip startup checks.
210
+
211
+ Keep local recovery ahead of user operations, give foreground commands priority, and drain Git cache cleanup before releasing sync locks. Startup observations are advisory and revalidated before manual operations. Cancelled or pre-commit failed reviews retain valid hints; successful fresh reviews clear superseded content-list mismatch hints. Setup summaries disclose conditional shutdown pushes, and recovery help remains available when state roots need repair.
212
+
213
+ ### Patch Changes
214
+
215
+ - 64b207b: Replace the initial setup purpose menu with direct name input, examples, and a brief explanation of suggested storage paths and separate sync choices. Blank names use `default`. Validate names and suggested backend locations before collecting connection details, and allow invalid names to be corrected immediately.
216
+ - 41eaa76: Simplify initial setup to one name across storage backends. Show input examples, explanations, and blank-to-accept defaults directly in Pi's dialogs without treating example endpoints or credentials as defaults. Default all new storage paths to the repository, WebDAV collection, or bucket root, without literal dot prefixes or changes to existing settings. New Git destinations use main, with existing branch safety checks preserved. Require a different path or Git branch before reviewing an additional setup when its chosen location is already configured. Preserve valid literal angle brackets in WebDAV input and edit defaults.
217
+ - 7af24f8: Keep initial R2/S3 storage paths identical in the setup review, saved settings, and resolved backend configuration. Setup names are independent of the default root path, including names with trailing slashes.
218
+ - f212568: Resolve the Git cache root to an absolute path so snapshot publication works when the cache path is relative and payload hashing changes the subprocess working directory.
219
+ - 12998a9: Simplify the setup-name prompt and distinguish its guidance with the theme's muted color.
220
+ - fdca695: Make setup choices explicit, retry invalid inputs, and show complete scrollable destination reviews. Clarify connection/setup menus and local save boundaries, retain drafts after recoverable save failures, and add actionable errors with bounded read-only S3 diagnostics.
221
+
222
+ ## 0.49.15
223
+
224
+ ### Patch Changes
225
+
226
+ - ec874c3: Add a global Settings option to skip push secret scanning while keeping the safe default and doctor diagnostics.
227
+
228
+ ## 0.49.14
229
+
230
+ ### Patch Changes
231
+
232
+ - Updated dependencies [40182e5]
233
+ - @narumitw/pi-tui-kit@0.59.0
234
+
235
+ ## 0.49.13
236
+
237
+ ### Patch Changes
238
+
239
+ - dc9802e: Keep Ctrl+C available as a hard-cancel input when configurable cancellation bindings are remapped.
240
+ - Updated dependencies [78276b0]
241
+ - Updated dependencies [dc9802e]
242
+ - @narumitw/pi-tui-kit@0.58.1
243
+
244
+ ## 0.49.12
245
+
246
+ ### Patch Changes
247
+
248
+ - 806eada: Reduce extension startup time by letting generated TypeScript chunks reference their emitted `.ts` files directly.
249
+
250
+ ## 0.49.11
251
+
252
+ ### Patch Changes
253
+
254
+ - 9224800: Load the extension from a generated split TypeScript runtime to reduce Jiti startup work while preserving existing first-use boundaries.
255
+
256
+ ## 0.49.10
257
+
258
+ ### Patch Changes
259
+
260
+ - e3375f0: Avoid migration-lock contention during normal state access and safely share legacy migration protection across overlapping work in one Pi process.
261
+
262
+ ## 0.49.9
263
+
264
+ ### Patch Changes
265
+
266
+ - 38a36bb: Make interrupted-operation recovery immediately actionable in the sync manager, distinguish live and guarded operations from recoverable locks, confirm local-lock removal, and return directly to normal sync actions after recovery.
267
+
268
+ ## 0.49.8
269
+
270
+ ### Patch Changes
271
+
272
+ - f75f7e9: Open reviewed synced-content recovery when automatic or interactive TUI sync detects a content-list mismatch, preserve deferred attention in the manager and editor, and keep deterministic and non-TUI routes non-blocking.
273
+
274
+ ## 0.49.7
275
+
276
+ ### Patch Changes
277
+
278
+ - 549e626: Resolve differing local and remote synced-content lists inline with reviewed adoption, explicit continuation, and the existing safe force-push path.
279
+
280
+ ## 0.49.6
281
+
282
+ ### Patch Changes
283
+
284
+ - fa9c938: Reduce idle startup imports by loading Goal presentation, Chat networking and UI, and Sync operation-specific modules only when their routes require them.
285
+
286
+ ## 0.49.5
287
+
288
+ ### Patch Changes
289
+
290
+ - 8289ba9: Move operational state from `.pisync` to `pi-sync` with an explicit guarded migration and fail-closed path handling.
291
+ - Updated dependencies [736ca9e]
292
+ - @narumitw/pi-tui-kit@0.52.0
293
+
294
+ ## 0.49.4
295
+
296
+ ### Patch Changes
297
+
298
+ - 6432b4d: Make included-content intent portable across snapshots, add reviewed remote-policy adoption, pause sync on explicit policy divergence, and allow safe custom paths that exist only remotely.
@@ -2,7 +2,7 @@
2
2
  // @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
3
3
  import {
4
4
  confirmMergeReview
5
- } from "./chunk-5XZOC7FD.ts";
5
+ } from "./chunk-KHBPED6W.ts";
6
6
  import {
7
7
  captureMutationOwner
8
8
  } from "./chunk-UOHR7LRO.ts";
@@ -66,4 +66,4 @@ async function confirmAgentRefusalRetry(ctx, setup, evidence, validate, signal)
66
66
  export {
67
67
  confirmAgentRefusalRetry
68
68
  };
69
- //# sourceMappingURL=agent-refusal-retry-AH7TXOQT.ts.map
69
+ //# sourceMappingURL=agent-refusal-retry-RPTMUQXK.ts.map
@@ -10,7 +10,7 @@ import {
10
10
  } from "./chunk-ORGBI36T.ts";
11
11
  import {
12
12
  confirmMergeReview
13
- } from "./chunk-5XZOC7FD.ts";
13
+ } from "./chunk-KHBPED6W.ts";
14
14
  import {
15
15
  conflictArtifactFingerprint,
16
16
  conflictDirectory,
@@ -1977,4 +1977,4 @@ export {
1977
1977
  createSyncDecision,
1978
1978
  mergeSync
1979
1979
  };
1980
- //# sourceMappingURL=chunk-N5TFMPB5.ts.map
1980
+ //# sourceMappingURL=chunk-6FVVRTL5.ts.map
@@ -60,6 +60,9 @@ function createSyncConfirmation(options) {
60
60
  if (item.value === choice && (choice !== "approve" || reviewed)) finish(choice);
61
61
  };
62
62
  const component = {
63
+ get capturesViewportInput() {
64
+ return list.capturesViewportInput;
65
+ },
63
66
  render(width, expose = true) {
64
67
  if (!Number.isFinite(width) || width <= 0) {
65
68
  reviewed = false;
@@ -212,4 +215,4 @@ async function confirmMergeReview(ctx, title, content, signal, isCurrent, confir
212
215
  export {
213
216
  confirmMergeReview
214
217
  };
215
- //# sourceMappingURL=chunk-5XZOC7FD.ts.map
218
+ //# sourceMappingURL=chunk-KHBPED6W.ts.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/ui/merge-review.ts", "../../src/ui/sync-confirmation.ts"],
4
+ "sourcesContent": ["import type { ExtensionCommandContext, ExtensionContext } from \"@earendil-works/pi-coding-agent\";\nimport { truncateToWidth } from \"@earendil-works/pi-tui\";\nimport { defineMenu, runCustomInteraction, runDocumentReview, runMenu } from \"@narumitw/pi-tui-kit\";\nimport { createSyncConfirmation, type SyncConfirmationChoice } from \"./sync-confirmation.js\";\nimport { safeTerminalText } from \"./terminal-text.js\";\n\ntype ReviewContext = ExtensionCommandContext | ExtensionContext;\n\n/** One approval screen; full details are optional and never authorize a transfer. */\nexport async function confirmMergeReview(\n ctx: ReviewContext,\n title: string,\n content: string,\n signal: AbortSignal | undefined,\n isCurrent: () => boolean,\n confirmationLabel = \"apply changes\",\n summaryLines?: readonly string[],\n) {\n const lines = summaryLines ?? [\n ...content\n .split(\"\\n\")\n .slice(0, 6)\n .map((line) => truncateToWidth(safeTerminalText(line), 100)),\n \"View details for the complete review.\",\n ];\n while (isCurrent() && !signal?.aborted) {\n const choice: { value: \"cancel\" | \"approve\" | \"details\" } = { value: \"cancel\" };\n const menu = defineMenu<undefined, \"confirm\", \"choose\", ReviewContext>({\n start: \"confirm\",\n screens: {\n confirm: () => ({\n kind: \"choice\",\n title,\n lines,\n initialItemId: \"cancel\",\n items: [\n { id: \"cancel\", label: \"No, cancel\" },\n { id: \"approve\", label: `Yes, ${confirmationLabel}` },\n { id: \"details\", label: \"View details\" },\n ],\n action: \"choose\",\n hint: \"close\",\n }),\n },\n actions: {\n choose: ({ itemId }) => {\n if (itemId === \"approve\" || itemId === \"details\") choice.value = itemId;\n return { kind: \"close\" };\n },\n },\n });\n const result =\n ctx.mode === \"tui\" && ctx.hasUI\n ? await runCustomInteraction<SyncConfirmationChoice, ReviewContext>(ctx, {\n create: ({ tui, theme, keybindings, complete }) =>\n createSyncConfirmation({ title, lines, confirmationLabel, tui, theme, keybindings, complete }),\n signal,\n isCurrent,\n onError: () => {},\n })\n : await runMenu(ctx, menu, { getState: () => undefined, signal, isCurrent, onError: () => {} });\n if (!isCurrent() || signal?.aborted) return false;\n if (result.kind === \"error\") throw new Error(\"Sync review failed; no transfer was performed.\");\n if (result.kind === \"unsupported\")\n throw new Error(\"Sync review requires observable TUI or RPC; review the plan before using --yes.\");\n if (result.kind === \"completed\") choice.value = result.value;\n else if (result.kind !== \"closed\") return false;\n // Keep authorization separate from UI termination in both adapters.\n if (choice.value === \"approve\") return true;\n if (choice.value !== \"details\") return false;\n const detail = await runDocumentReview(ctx, {\n title: \"Sync change details\",\n content,\n format: { kind: \"text\" },\n viewportSize: \"adaptive\",\n hint: \"back\",\n signal,\n isCurrent,\n onError: () => {},\n });\n if (!isCurrent() || signal?.aborted) return false;\n if (detail.kind === \"error\") throw new Error(\"Sync review failed; no transfer was performed.\");\n if (detail.kind !== \"cancelled\" || detail.reason !== \"back\") return false;\n // A fresh menu discards remembered selection: returning from details always selects No.\n // Unlike Pi's native Yes-first dialog, approval requires moving off the safe default.\n }\n return false;\n}\n", "import type { KeybindingsManager, Theme } from \"@earendil-works/pi-coding-agent\";\nimport { Key, matchesKey, SelectList, type TUI, type TuiMouseEvent, truncateToWidth } from \"@earendil-works/pi-tui\";\nimport { HorizontalRule, hardWrapTerminalDocument, sanitizeTerminalText } from \"@narumitw/pi-tui-kit\";\n\nexport type SyncConfirmationChoice = \"cancel\" | \"approve\" | \"details\";\n\n/** Kit choice context is clipped on short terminals; this summary must remain reviewable. */\nexport function createSyncConfirmation(options: {\n title: string;\n lines: readonly string[];\n confirmationLabel: string;\n tui: TUI;\n theme: Theme;\n keybindings: KeybindingsManager;\n complete(choice: SyncConfirmationChoice): void;\n}) {\n const { tui, theme, keybindings } = options;\n const choices: SyncConfirmationChoice[] = [\"cancel\", \"approve\", \"details\"];\n const list = new SelectList(\n [\n { value: \"cancel\", label: \"No, cancel\" },\n { value: \"approve\", label: `Yes, ${sanitizeTerminalText(options.confirmationLabel)}` },\n { value: \"details\", label: \"View details\" },\n ],\n 3,\n {\n selectedPrefix: (text) => theme.fg(\"accent\", text),\n selectedText: (text) => theme.fg(\"accent\", text),\n description: (text) => theme.fg(\"muted\", text),\n scrollInfo: (text) => theme.fg(\"dim\", text),\n noMatch: (text) => theme.fg(\"muted\", text),\n },\n );\n const rule = new HorizontalRule({ ruleStyle: (text) => theme.fg(\"border\", text) });\n let selected = 0;\n let offset = 0;\n let maximumOffset = 0;\n let lastWidth = 0;\n let lastRows = 0;\n let seen = new Set<number>();\n let summary: readonly string[] = [];\n let reviewed = false;\n let disposed = false;\n let finished = false;\n let summaryStart = 0;\n let summaryEnd = 0;\n let actionsStart = 0;\n const finish = (choice: SyncConfirmationChoice) => {\n if (disposed || finished) return;\n finished = true;\n options.complete(choice);\n };\n const select = (index: number) => {\n selected = (index + choices.length) % choices.length;\n list.setSelectedIndex(selected);\n };\n list.onSelectionChange = (item) => {\n selected = Math.max(0, choices.indexOf(item.value as SyncConfirmationChoice));\n };\n list.onSelect = (item) => {\n const choice = choices[selected] ?? \"cancel\";\n if (item.value === choice && (choice !== \"approve\" || reviewed)) finish(choice);\n };\n const component = {\n get capturesViewportInput() {\n return list.capturesViewportInput;\n },\n render(width: number, expose = true): string[] {\n if (!Number.isFinite(width) || width <= 0) {\n reviewed = false;\n return [];\n }\n const cells = Math.floor(width);\n const rows = Math.max(1, Math.floor(tui.terminal.rows) - 3);\n if (cells !== lastWidth || rows !== lastRows) {\n // Reflow can expose previously unseen rows or hide the selected action.\n // Reset proof and selection rather than carry approval across a resize.\n summary = options.lines.flatMap((line) => hardWrapTerminalDocument(line, cells));\n seen = new Set();\n offset = 0;\n select(0);\n lastWidth = cells;\n lastRows = rows;\n }\n const framed = rows >= 9;\n const actions = list.render(cells);\n const viewport = Math.max(0, rows - actions.length - 3 - (framed ? 2 : 0));\n maximumOffset = Math.max(0, summary.length - viewport);\n offset = Math.min(offset, maximumOffset);\n const visible = summary.slice(offset, offset + viewport);\n if (expose) for (let index = offset; index < offset + visible.length; index++) seen.add(index);\n reviewed = viewport > 0 && seen.size === summary.length;\n // Describe actions without advertising configured keys that can be invalid,\n // aliased, or shadowed by an earlier cancellation/navigation binding.\n const hint = reviewed ? \"Select an action.\" : \"Navigation keys scroll the summary before selecting Yes.\";\n const body = [\n theme.fg(\"accent\", theme.bold(hardWrapTerminalDocument(options.title, cells).join(\" \"))),\n ...visible.map((line) => theme.fg(\"text\", line)),\n theme.fg(\n \"muted\",\n `Summary ${visible.length ? offset + 1 : 0}-${offset + visible.length}/${summary.length}${reviewed ? \"\" : \" \u2014 review before Yes\"}`,\n ),\n ...actions,\n theme.fg(\"dim\", hint),\n ];\n summaryStart = Number(framed) + 1;\n summaryEnd = summaryStart + visible.length;\n actionsStart = summaryEnd + 1;\n const frame = framed ? [...rule.render(cells), ...body, ...rule.render(cells)] : body;\n // Very small terminals cannot display the summary and all choices together.\n // Keep cancellation available, but never approve a zero-row summary viewport.\n return frame.slice(0, rows).map((line) => truncateToWidth(line, cells, \"\"));\n },\n invalidate() {\n list.invalidate();\n rule.invalidate();\n },\n handleInput(data: string) {\n if (disposed || finished) return;\n if (matchesKey(data, Key.ctrl(\"c\")) || keybindings.matches(data, \"tui.select.cancel\")) {\n finish(\"cancel\");\n return;\n }\n // Refresh height/width proof before handling an input racing with terminal resize.\n component.render(tui.terminal.columns ?? lastWidth, false);\n if (keybindings.matches(data, \"tui.select.up\")) {\n if (!reviewed || (selected === 0 && offset > 0)) offset = Math.max(0, offset - 1);\n else select(selected - 1);\n } else if (keybindings.matches(data, \"tui.select.down\")) {\n if (!reviewed || (selected === 0 && offset < maximumOffset)) offset = Math.min(maximumOffset, offset + 1);\n else select(selected + 1);\n } else if (keybindings.matches(data, \"tui.select.confirm\")) {\n const choice = choices[selected] ?? \"cancel\";\n if (choice !== \"approve\" || reviewed) finish(choice);\n }\n tui.requestRender();\n },\n handleMouse(event: TuiMouseEvent) {\n if (disposed || finished || event.width !== lastWidth) return undefined;\n component.render(event.width, false);\n if (event.y >= summaryStart && event.y < summaryEnd && event.type === \"wheel\" && event.wheelDelta) {\n offset = Math.max(0, Math.min(maximumOffset, offset + (event.wheelDelta < 0 ? -1 : 1)));\n select(0);\n tui.requestRender();\n return { handled: true, render: true };\n }\n if (event.y < actionsStart || event.y >= actionsStart + choices.length || event.y >= lastRows) return undefined;\n return list.handleMouse({ ...event, y: event.y - actionsStart, height: choices.length });\n },\n dispose() {\n disposed = true;\n seen.clear();\n },\n };\n return component;\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["truncateToWidth", "truncateToWidth"]
7
+ }
@@ -69,7 +69,7 @@ async function withAgentSyncLock(ctx, options, run) {
69
69
  expectedRefusal = parseAgentCandidate(JSON.stringify(cached), request.evidence);
70
70
  if (!expectedRefusal.results.some((row) => "refuse" in row))
71
71
  throw new Error("The current cached result is not a refusal. Use Sync now.");
72
- const { confirmAgentRefusalRetry } = await import("./agent-refusal-retry-AH7TXOQT.ts");
72
+ const { confirmAgentRefusalRetry } = await import("./agent-refusal-retry-RPTMUQXK.ts");
73
73
  options.signal?.throwIfAborted();
74
74
  if (!await confirmAgentRefusalRetry(ctx, options.setup, request.evidence, validate, options.signal))
75
75
  return "cancelled";
@@ -137,4 +137,4 @@ async function withAgentSyncLock(ctx, options, run) {
137
137
  export {
138
138
  withAgentSyncLock
139
139
  };
140
- //# sourceMappingURL=chunk-WD6FJHCK.ts.map
140
+ //# sourceMappingURL=chunk-MKKF4IMY.ts.map
@@ -2,14 +2,14 @@
2
2
  // @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
3
3
  import {
4
4
  mergeSync
5
- } from "./chunk-N5TFMPB5.ts";
5
+ } from "./chunk-6FVVRTL5.ts";
6
6
  import "./chunk-YK52VDXG.ts";
7
7
  import {
8
8
  createSyncBackend
9
9
  } from "./chunk-ORGBI36T.ts";
10
10
  import {
11
11
  confirmMergeReview
12
- } from "./chunk-5XZOC7FD.ts";
12
+ } from "./chunk-KHBPED6W.ts";
13
13
  import {
14
14
  conflictArtifactFingerprint,
15
15
  readConflictArtifact
@@ -180,4 +180,4 @@ async function showConflicts(ctx, options, factory = createSyncBackend) {
180
180
  export {
181
181
  showConflicts
182
182
  };
183
- //# sourceMappingURL=conflict-review-UC5AGVER.ts.map
183
+ //# sourceMappingURL=conflict-review-3X37QEIT.ts.map
@@ -17,7 +17,7 @@ import {
17
17
  } from "./chunk-BDB4IDM3.ts";
18
18
  import {
19
19
  withAgentSyncLock
20
- } from "./chunk-WD6FJHCK.ts";
20
+ } from "./chunk-MKKF4IMY.ts";
21
21
  import "./chunk-3ST7RSYN.ts";
22
22
  import {
23
23
  createStartupTimings
@@ -569,4 +569,4 @@ export {
569
569
  continuousEnabled,
570
570
  createContinuousSync
571
571
  };
572
- //# sourceMappingURL=continuous-sync-POEQXR25.ts.map
572
+ //# sourceMappingURL=continuous-sync-Q6QUD6TY.ts.map
@@ -37,7 +37,7 @@ import {
37
37
  } from "./chunk-GP5DU62N.ts";
38
38
  import {
39
39
  confirmMergeReview
40
- } from "./chunk-5XZOC7FD.ts";
40
+ } from "./chunk-KHBPED6W.ts";
41
41
  import {
42
42
  addStorageConnection,
43
43
  removeStorageConnection,
@@ -2131,4 +2131,4 @@ function syncMainMenuItem(label) {
2131
2131
  export {
2132
2132
  showSyncManager
2133
2133
  };
2134
- //# sourceMappingURL=manager-ui-26LEINEX.ts.map
2134
+ //# sourceMappingURL=manager-ui-ZH6DEC2G.ts.map
@@ -15,7 +15,7 @@ import {
15
15
  formatSnapshotOnlyDiff,
16
16
  mergeSync,
17
17
  publicationCapabilityDescription
18
- } from "./chunk-N5TFMPB5.ts";
18
+ } from "./chunk-6FVVRTL5.ts";
19
19
  import {
20
20
  formatRemoteSelectionStatus,
21
21
  readRemoteSnapshot,
@@ -27,7 +27,7 @@ import {
27
27
  } from "./chunk-ORGBI36T.ts";
28
28
  import {
29
29
  confirmMergeReview
30
- } from "./chunk-5XZOC7FD.ts";
30
+ } from "./chunk-KHBPED6W.ts";
31
31
  import "./chunk-ED3TYIVW.ts";
32
32
  import {
33
33
  readMergeJournal,
@@ -1009,4 +1009,4 @@ export {
1009
1009
  status,
1010
1010
  syncBoth
1011
1011
  };
1012
- //# sourceMappingURL=sync-operations-ZHA6HQDB.ts.map
1012
+ //# sourceMappingURL=sync-operations-Y72GNIQ2.ts.map
package/dist/index.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  // @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
3
3
  import {
4
4
  withAgentSyncLock
5
- } from "./chunks/chunk-WD6FJHCK.ts";
5
+ } from "./chunks/chunk-MKKF4IMY.ts";
6
6
  import "./chunks/chunk-3ST7RSYN.ts";
7
7
  import {
8
8
  recoverSnapshotTransactionsOnStartup
@@ -219,7 +219,7 @@ async function executeCommand(rawArgs, ctx, signal, loaders, onCommit, setup, on
219
219
  return { kind: "completed" };
220
220
  }
221
221
  case "conflicts": {
222
- const { showConflicts } = await import("./chunks/conflict-review-UC5AGVER.ts");
222
+ const { showConflicts } = await import("./chunks/conflict-review-3X37QEIT.ts");
223
223
  throwIfAborted(options.signal);
224
224
  await withLock("sync", () => showConflicts(ctx, options));
225
225
  return { kind: "completed" };
@@ -434,7 +434,7 @@ async function handleCommand(rawArgs, ctx, sessionSignal, loaders, attention, on
434
434
  };
435
435
  if (!rawArgs.trim()) {
436
436
  try {
437
- const { showSyncManager } = await import("./chunks/manager-ui-26LEINEX.ts");
437
+ const { showSyncManager } = await import("./chunks/manager-ui-ZH6DEC2G.ts");
438
438
  if (sessionSignal.aborted) return;
439
439
  await showSyncManager(ctx, run, sessionSignal, {
440
440
  getAttention: () => attention.current(),
@@ -851,7 +851,7 @@ function createSyncLoaders(dependencies) {
851
851
  setupSwitch: cachedModuleLoader(dependencies.loadSetupSwitch ?? (() => import("./chunks/setup-switch-E7PHKI6J.ts"))),
852
852
  snapshot: cachedModuleLoader(dependencies.loadSnapshot ?? (() => import("./chunks/snapshot-THS5EY2L.ts"))),
853
853
  syncState: cachedModuleLoader(dependencies.loadSyncState ?? (() => import("./chunks/sync-state-CFL4RRRB.ts"))),
854
- operations: cachedModuleLoader(dependencies.loadSyncOperations ?? (() => import("./chunks/sync-operations-ZHA6HQDB.ts")))
854
+ operations: cachedModuleLoader(dependencies.loadSyncOperations ?? (() => import("./chunks/sync-operations-Y72GNIQ2.ts")))
855
855
  };
856
856
  return loaders;
857
857
  }
@@ -918,7 +918,7 @@ function sync(pi, dependencies = {}) {
918
918
  await continuous?.stop(ctx.sessionManager);
919
919
  return;
920
920
  }
921
- const { createContinuousSync } = await import("./chunks/continuous-sync-POEQXR25.ts");
921
+ const { createContinuousSync } = await import("./chunks/continuous-sync-Q6QUD6TY.ts");
922
922
  if (!isCurrent()) return;
923
923
  continuous ??= createContinuousSync(loaders, void 0, publishTimings);
924
924
  continuous.start(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@narumitw/pi-sync",
3
- "version": "0.57.8",
3
+ "version": "0.57.9",
4
4
  "description": "Pi extension that syncs Pi configuration through Git, WebDAV, Cloudflare R2, or S3-compatible storage.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -27,6 +27,7 @@
27
27
  "docs",
28
28
  "skills",
29
29
  "README.md",
30
+ "CHANGELOG.md",
30
31
  "LICENSE"
31
32
  ],
32
33
  "pi": {
@@ -45,14 +46,14 @@
45
46
  "typecheck": "tsc --noEmit"
46
47
  },
47
48
  "dependencies": {
48
- "@narumitw/pi-tui-kit": "^0.68.1",
49
+ "@narumitw/pi-tui-kit": "^0.69.0",
49
50
  "fast-xml-parser": "^5.11.2",
50
51
  "proper-lockfile": "^4.1.2",
51
52
  "semver": "^7.8.5"
52
53
  },
53
54
  "devDependencies": {
54
- "@earendil-works/pi-coding-agent": "1.4.0",
55
- "@earendil-works/pi-tui": "1.4.0",
55
+ "@earendil-works/pi-coding-agent": "1.5.0",
56
+ "@earendil-works/pi-tui": "1.5.0",
56
57
  "@types/proper-lockfile": "^4.1.4",
57
58
  "@types/semver": "^7.8.0",
58
59
  "esbuild": "0.28.2",
@@ -62,6 +62,9 @@ export function createSyncConfirmation(options: {
62
62
  if (item.value === choice && (choice !== "approve" || reviewed)) finish(choice);
63
63
  };
64
64
  const component = {
65
+ get capturesViewportInput() {
66
+ return list.capturesViewportInput;
67
+ },
65
68
  render(width: number, expose = true): string[] {
66
69
  if (!Number.isFinite(width) || width <= 0) {
67
70
  reviewed = false;
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/ui/merge-review.ts", "../../src/ui/sync-confirmation.ts"],
4
- "sourcesContent": ["import type { ExtensionCommandContext, ExtensionContext } from \"@earendil-works/pi-coding-agent\";\nimport { truncateToWidth } from \"@earendil-works/pi-tui\";\nimport { defineMenu, runCustomInteraction, runDocumentReview, runMenu } from \"@narumitw/pi-tui-kit\";\nimport { createSyncConfirmation, type SyncConfirmationChoice } from \"./sync-confirmation.js\";\nimport { safeTerminalText } from \"./terminal-text.js\";\n\ntype ReviewContext = ExtensionCommandContext | ExtensionContext;\n\n/** One approval screen; full details are optional and never authorize a transfer. */\nexport async function confirmMergeReview(\n ctx: ReviewContext,\n title: string,\n content: string,\n signal: AbortSignal | undefined,\n isCurrent: () => boolean,\n confirmationLabel = \"apply changes\",\n summaryLines?: readonly string[],\n) {\n const lines = summaryLines ?? [\n ...content\n .split(\"\\n\")\n .slice(0, 6)\n .map((line) => truncateToWidth(safeTerminalText(line), 100)),\n \"View details for the complete review.\",\n ];\n while (isCurrent() && !signal?.aborted) {\n const choice: { value: \"cancel\" | \"approve\" | \"details\" } = { value: \"cancel\" };\n const menu = defineMenu<undefined, \"confirm\", \"choose\", ReviewContext>({\n start: \"confirm\",\n screens: {\n confirm: () => ({\n kind: \"choice\",\n title,\n lines,\n initialItemId: \"cancel\",\n items: [\n { id: \"cancel\", label: \"No, cancel\" },\n { id: \"approve\", label: `Yes, ${confirmationLabel}` },\n { id: \"details\", label: \"View details\" },\n ],\n action: \"choose\",\n hint: \"close\",\n }),\n },\n actions: {\n choose: ({ itemId }) => {\n if (itemId === \"approve\" || itemId === \"details\") choice.value = itemId;\n return { kind: \"close\" };\n },\n },\n });\n const result =\n ctx.mode === \"tui\" && ctx.hasUI\n ? await runCustomInteraction<SyncConfirmationChoice, ReviewContext>(ctx, {\n create: ({ tui, theme, keybindings, complete }) =>\n createSyncConfirmation({ title, lines, confirmationLabel, tui, theme, keybindings, complete }),\n signal,\n isCurrent,\n onError: () => {},\n })\n : await runMenu(ctx, menu, { getState: () => undefined, signal, isCurrent, onError: () => {} });\n if (!isCurrent() || signal?.aborted) return false;\n if (result.kind === \"error\") throw new Error(\"Sync review failed; no transfer was performed.\");\n if (result.kind === \"unsupported\")\n throw new Error(\"Sync review requires observable TUI or RPC; review the plan before using --yes.\");\n if (result.kind === \"completed\") choice.value = result.value;\n else if (result.kind !== \"closed\") return false;\n // Keep authorization separate from UI termination in both adapters.\n if (choice.value === \"approve\") return true;\n if (choice.value !== \"details\") return false;\n const detail = await runDocumentReview(ctx, {\n title: \"Sync change details\",\n content,\n format: { kind: \"text\" },\n viewportSize: \"adaptive\",\n hint: \"back\",\n signal,\n isCurrent,\n onError: () => {},\n });\n if (!isCurrent() || signal?.aborted) return false;\n if (detail.kind === \"error\") throw new Error(\"Sync review failed; no transfer was performed.\");\n if (detail.kind !== \"cancelled\" || detail.reason !== \"back\") return false;\n // A fresh menu discards remembered selection: returning from details always selects No.\n // Unlike Pi's native Yes-first dialog, approval requires moving off the safe default.\n }\n return false;\n}\n", "import type { KeybindingsManager, Theme } from \"@earendil-works/pi-coding-agent\";\nimport { Key, matchesKey, SelectList, type TUI, type TuiMouseEvent, truncateToWidth } from \"@earendil-works/pi-tui\";\nimport { HorizontalRule, hardWrapTerminalDocument, sanitizeTerminalText } from \"@narumitw/pi-tui-kit\";\n\nexport type SyncConfirmationChoice = \"cancel\" | \"approve\" | \"details\";\n\n/** Kit choice context is clipped on short terminals; this summary must remain reviewable. */\nexport function createSyncConfirmation(options: {\n title: string;\n lines: readonly string[];\n confirmationLabel: string;\n tui: TUI;\n theme: Theme;\n keybindings: KeybindingsManager;\n complete(choice: SyncConfirmationChoice): void;\n}) {\n const { tui, theme, keybindings } = options;\n const choices: SyncConfirmationChoice[] = [\"cancel\", \"approve\", \"details\"];\n const list = new SelectList(\n [\n { value: \"cancel\", label: \"No, cancel\" },\n { value: \"approve\", label: `Yes, ${sanitizeTerminalText(options.confirmationLabel)}` },\n { value: \"details\", label: \"View details\" },\n ],\n 3,\n {\n selectedPrefix: (text) => theme.fg(\"accent\", text),\n selectedText: (text) => theme.fg(\"accent\", text),\n description: (text) => theme.fg(\"muted\", text),\n scrollInfo: (text) => theme.fg(\"dim\", text),\n noMatch: (text) => theme.fg(\"muted\", text),\n },\n );\n const rule = new HorizontalRule({ ruleStyle: (text) => theme.fg(\"border\", text) });\n let selected = 0;\n let offset = 0;\n let maximumOffset = 0;\n let lastWidth = 0;\n let lastRows = 0;\n let seen = new Set<number>();\n let summary: readonly string[] = [];\n let reviewed = false;\n let disposed = false;\n let finished = false;\n let summaryStart = 0;\n let summaryEnd = 0;\n let actionsStart = 0;\n const finish = (choice: SyncConfirmationChoice) => {\n if (disposed || finished) return;\n finished = true;\n options.complete(choice);\n };\n const select = (index: number) => {\n selected = (index + choices.length) % choices.length;\n list.setSelectedIndex(selected);\n };\n list.onSelectionChange = (item) => {\n selected = Math.max(0, choices.indexOf(item.value as SyncConfirmationChoice));\n };\n list.onSelect = (item) => {\n const choice = choices[selected] ?? \"cancel\";\n if (item.value === choice && (choice !== \"approve\" || reviewed)) finish(choice);\n };\n const component = {\n render(width: number, expose = true): string[] {\n if (!Number.isFinite(width) || width <= 0) {\n reviewed = false;\n return [];\n }\n const cells = Math.floor(width);\n const rows = Math.max(1, Math.floor(tui.terminal.rows) - 3);\n if (cells !== lastWidth || rows !== lastRows) {\n // Reflow can expose previously unseen rows or hide the selected action.\n // Reset proof and selection rather than carry approval across a resize.\n summary = options.lines.flatMap((line) => hardWrapTerminalDocument(line, cells));\n seen = new Set();\n offset = 0;\n select(0);\n lastWidth = cells;\n lastRows = rows;\n }\n const framed = rows >= 9;\n const actions = list.render(cells);\n const viewport = Math.max(0, rows - actions.length - 3 - (framed ? 2 : 0));\n maximumOffset = Math.max(0, summary.length - viewport);\n offset = Math.min(offset, maximumOffset);\n const visible = summary.slice(offset, offset + viewport);\n if (expose) for (let index = offset; index < offset + visible.length; index++) seen.add(index);\n reviewed = viewport > 0 && seen.size === summary.length;\n // Describe actions without advertising configured keys that can be invalid,\n // aliased, or shadowed by an earlier cancellation/navigation binding.\n const hint = reviewed ? \"Select an action.\" : \"Navigation keys scroll the summary before selecting Yes.\";\n const body = [\n theme.fg(\"accent\", theme.bold(hardWrapTerminalDocument(options.title, cells).join(\" \"))),\n ...visible.map((line) => theme.fg(\"text\", line)),\n theme.fg(\n \"muted\",\n `Summary ${visible.length ? offset + 1 : 0}-${offset + visible.length}/${summary.length}${reviewed ? \"\" : \" \u2014 review before Yes\"}`,\n ),\n ...actions,\n theme.fg(\"dim\", hint),\n ];\n summaryStart = Number(framed) + 1;\n summaryEnd = summaryStart + visible.length;\n actionsStart = summaryEnd + 1;\n const frame = framed ? [...rule.render(cells), ...body, ...rule.render(cells)] : body;\n // Very small terminals cannot display the summary and all choices together.\n // Keep cancellation available, but never approve a zero-row summary viewport.\n return frame.slice(0, rows).map((line) => truncateToWidth(line, cells, \"\"));\n },\n invalidate() {\n list.invalidate();\n rule.invalidate();\n },\n handleInput(data: string) {\n if (disposed || finished) return;\n if (matchesKey(data, Key.ctrl(\"c\")) || keybindings.matches(data, \"tui.select.cancel\")) {\n finish(\"cancel\");\n return;\n }\n // Refresh height/width proof before handling an input racing with terminal resize.\n component.render(tui.terminal.columns ?? lastWidth, false);\n if (keybindings.matches(data, \"tui.select.up\")) {\n if (!reviewed || (selected === 0 && offset > 0)) offset = Math.max(0, offset - 1);\n else select(selected - 1);\n } else if (keybindings.matches(data, \"tui.select.down\")) {\n if (!reviewed || (selected === 0 && offset < maximumOffset)) offset = Math.min(maximumOffset, offset + 1);\n else select(selected + 1);\n } else if (keybindings.matches(data, \"tui.select.confirm\")) {\n const choice = choices[selected] ?? \"cancel\";\n if (choice !== \"approve\" || reviewed) finish(choice);\n }\n tui.requestRender();\n },\n handleMouse(event: TuiMouseEvent) {\n if (disposed || finished || event.width !== lastWidth) return undefined;\n component.render(event.width, false);\n if (event.y >= summaryStart && event.y < summaryEnd && event.type === \"wheel\" && event.wheelDelta) {\n offset = Math.max(0, Math.min(maximumOffset, offset + (event.wheelDelta < 0 ? -1 : 1)));\n select(0);\n tui.requestRender();\n return { handled: true, render: true };\n }\n if (event.y < actionsStart || event.y >= actionsStart + choices.length || event.y >= lastRows) return undefined;\n return list.handleMouse({ ...event, y: event.y - actionsStart, height: choices.length });\n },\n dispose() {\n disposed = true;\n seen.clear();\n },\n };\n return component;\n}\n"],
5
- "mappings": "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",
6
- "names": ["truncateToWidth", "truncateToWidth"]
7
- }