@narumitw/pi-sync 0.57.12 → 0.58.0

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 (46) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +2 -0
  3. package/dist/chunks/{agent-sync-P6AWQXGK.ts → agent-sync-2R4GG2MF.ts} +3 -3
  4. package/dist/chunks/{chunk-ZDDBZH72.ts → chunk-JYILGR3K.ts} +2 -2
  5. package/dist/chunks/{chunk-OKPPZA4D.ts → chunk-MG66XM5U.ts} +3 -3
  6. package/dist/chunks/{chunk-OKPPZA4D.ts.map → chunk-MG66XM5U.ts.map} +2 -2
  7. package/dist/chunks/{chunk-Q23JJW7E.ts → chunk-MW6KUQYA.ts} +7 -5
  8. package/dist/chunks/chunk-MW6KUQYA.ts.map +7 -0
  9. package/dist/chunks/{chunk-ZC3IHFNM.ts → chunk-WQMYV4DW.ts} +3 -3
  10. package/dist/chunks/chunk-WQMYV4DW.ts.map +7 -0
  11. package/dist/chunks/chunk-YIPK23JW.ts +171 -0
  12. package/dist/chunks/chunk-YIPK23JW.ts.map +7 -0
  13. package/dist/chunks/{command-handler-VKLZBRLO.ts → command-handler-KCB6MCWS.ts} +6 -6
  14. package/dist/chunks/{continuous-sync-TTOSJCQU.ts → continuous-sync-FAFNLEUW.ts} +18 -10
  15. package/dist/chunks/continuous-sync-FAFNLEUW.ts.map +7 -0
  16. package/dist/chunks/{manager-result-dispatcher-6W52NM7F.ts → manager-result-dispatcher-XCYPW7RC.ts} +4 -4
  17. package/dist/chunks/{manager-ui-INVMAFEN.ts → manager-ui-FMZXKPX2.ts} +8 -8
  18. package/dist/chunks/{remote-selection-ui-TD4C4W3J.ts → remote-selection-ui-MYM2YCPF.ts} +3 -3
  19. package/dist/chunks/{sync-operations-TMGQHBF5.ts → sync-operations-45APGOL3.ts} +6 -6
  20. package/dist/chunks/sync-operations-45APGOL3.ts.map +7 -0
  21. package/dist/index.ts +78 -63
  22. package/dist/index.ts.map +2 -2
  23. package/docs/tui-contract.md +37 -0
  24. package/package.json +1 -1
  25. package/skills/configure-pi-sync/references/configuration.md +13 -1
  26. package/src/sync/agent-sync.ts +1 -1
  27. package/src/sync/continuous-sync.ts +15 -6
  28. package/src/sync/startup-check.ts +1 -1
  29. package/src/sync/sync-mutations.ts +2 -2
  30. package/src/sync/sync-queries.ts +2 -2
  31. package/src/sync-extension.ts +71 -57
  32. package/src/ui/remote-selection-ui.ts +1 -1
  33. package/src/ui/sync-attention.ts +5 -3
  34. package/src/ui/sync-status.ts +214 -3
  35. package/dist/chunks/chunk-K3RIEL6J.ts +0 -20
  36. package/dist/chunks/chunk-K3RIEL6J.ts.map +0 -7
  37. package/dist/chunks/chunk-Q23JJW7E.ts.map +0 -7
  38. package/dist/chunks/chunk-ZC3IHFNM.ts.map +0 -7
  39. package/dist/chunks/continuous-sync-TTOSJCQU.ts.map +0 -7
  40. package/dist/chunks/sync-operations-TMGQHBF5.ts.map +0 -7
  41. /package/dist/chunks/{agent-sync-P6AWQXGK.ts.map → agent-sync-2R4GG2MF.ts.map} +0 -0
  42. /package/dist/chunks/{chunk-ZDDBZH72.ts.map → chunk-JYILGR3K.ts.map} +0 -0
  43. /package/dist/chunks/{command-handler-VKLZBRLO.ts.map → command-handler-KCB6MCWS.ts.map} +0 -0
  44. /package/dist/chunks/{manager-result-dispatcher-6W52NM7F.ts.map → manager-result-dispatcher-XCYPW7RC.ts.map} +0 -0
  45. /package/dist/chunks/{manager-ui-INVMAFEN.ts.map → manager-ui-FMZXKPX2.ts.map} +0 -0
  46. /package/dist/chunks/{remote-selection-ui-TD4C4W3J.ts.map → remote-selection-ui-MYM2YCPF.ts.map} +0 -0
@@ -0,0 +1,171 @@
1
+ // @generated by scripts/build-runtime.mjs; do not edit.
2
+ // @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
3
+
4
+ // src/ui/sync-status.ts
5
+ var STATUS_KEY = "sync";
6
+ var failureReasons = {
7
+ transient: "temp",
8
+ contention: "busy",
9
+ stale: "stale",
10
+ authentication: "auth",
11
+ storage: "storage",
12
+ unsafe: "review",
13
+ model: "model",
14
+ budget: "limit",
15
+ unknown: "unknown"
16
+ };
17
+ function syncStatusFailureReason(kind) {
18
+ return typeof kind === "string" && Object.hasOwn(failureReasons, kind) ? failureReasons[kind] : "unknown";
19
+ }
20
+ var enabledBySession = /* @__PURE__ */ new WeakMap();
21
+ var publishersBySession = /* @__PURE__ */ new WeakMap();
22
+ function statusPresentation(presentation) {
23
+ if (!presentation) return;
24
+ try {
25
+ const { activity, reason } = presentation;
26
+ if (activity === "retry" || activity === "blocked") {
27
+ if (typeof reason === "string" && /^[a-z][a-z0-9-]{0,31}$/u.exec(reason)?.[0] === reason)
28
+ return { activity, reason };
29
+ } else if ([
30
+ "idle",
31
+ "checking",
32
+ "working",
33
+ "pushing",
34
+ "pulling",
35
+ "resolving",
36
+ "local-change",
37
+ "remote-change",
38
+ "review"
39
+ ].includes(activity) && reason === void 0) {
40
+ return { activity };
41
+ }
42
+ } catch {
43
+ }
44
+ return void 0;
45
+ }
46
+ function createSyncStatusPublisher(events) {
47
+ let active;
48
+ let used = false;
49
+ let activation = 0;
50
+ const emit = (payload) => {
51
+ try {
52
+ events?.emit("extension-status:v1:update", payload);
53
+ } catch {
54
+ }
55
+ };
56
+ const bind = (ctx) => {
57
+ if (!ctx.hasUI || !active && used || active && active.sessionManager !== ctx.sessionManager) return () => {
58
+ };
59
+ const { sessionManager } = ctx;
60
+ if (active) {
61
+ return publishersBySession.get(sessionManager) === active.binding ? active.binding.release : () => {
62
+ };
63
+ }
64
+ const owner = activation;
65
+ used = true;
66
+ publishersBySession.get(sessionManager)?.release();
67
+ if (activation !== owner || publishersBySession.has(sessionManager)) return () => {
68
+ };
69
+ let current;
70
+ let revision = 0;
71
+ let unsubscribe;
72
+ const isCurrent = () => publishersBySession.get(sessionManager) === binding;
73
+ const publish = (requestId) => {
74
+ emit({
75
+ version: 1,
76
+ sessionManager,
77
+ key: STATUS_KEY,
78
+ ...current ?? { value: void 0 },
79
+ ...requestId === void 0 ? {} : { requestId }
80
+ });
81
+ };
82
+ const binding = {
83
+ update(value, presentation) {
84
+ if (!isCurrent()) return;
85
+ const owner2 = ++revision;
86
+ const safePresentation = statusPresentation(presentation);
87
+ if (!isCurrent() || revision !== owner2) return;
88
+ current = value && safePresentation ? { value, ...safePresentation } : void 0;
89
+ publish();
90
+ },
91
+ release() {
92
+ const owned = isCurrent();
93
+ revision++;
94
+ if (owned) {
95
+ publishersBySession.delete(sessionManager);
96
+ current = void 0;
97
+ }
98
+ if (active?.binding === binding) active = void 0;
99
+ const stop = unsubscribe;
100
+ unsubscribe = void 0;
101
+ try {
102
+ stop?.();
103
+ } catch {
104
+ }
105
+ if (owned && !publishersBySession.has(sessionManager)) publish();
106
+ }
107
+ };
108
+ active = { sessionManager, binding };
109
+ used = true;
110
+ publishersBySession.set(sessionManager, binding);
111
+ try {
112
+ unsubscribe = events?.on("extension-status:v1:request", (payload) => {
113
+ try {
114
+ if (!isCurrent() || !payload || typeof payload !== "object" || Array.isArray(payload)) return;
115
+ const {
116
+ version,
117
+ sessionManager: manager,
118
+ requestId
119
+ } = payload;
120
+ if (!isCurrent() || version !== 1 || manager !== sessionManager || !requestId || typeof requestId !== "object")
121
+ return;
122
+ publish(requestId);
123
+ } catch {
124
+ }
125
+ });
126
+ } catch {
127
+ }
128
+ return binding.release;
129
+ };
130
+ return {
131
+ bind,
132
+ start(ctx) {
133
+ const owner = ++activation;
134
+ const { sessionManager } = ctx;
135
+ const previous = publishersBySession.get(sessionManager);
136
+ active?.binding.release();
137
+ if (activation !== owner || publishersBySession.has(sessionManager) && publishersBySession.get(sessionManager) !== previous)
138
+ return () => {
139
+ };
140
+ used = false;
141
+ const release = bind(ctx);
142
+ used = true;
143
+ return activation === owner ? release : () => {
144
+ };
145
+ },
146
+ cleanupFor(ctx) {
147
+ return active?.sessionManager === ctx.sessionManager ? active.binding.release : () => {
148
+ };
149
+ }
150
+ };
151
+ }
152
+ function configureSyncStatus(ctx, enabled) {
153
+ enabledBySession.set(ctx.sessionManager, enabled);
154
+ if (!enabled) {
155
+ if (ctx.hasUI) ctx.ui.setStatus(STATUS_KEY, void 0);
156
+ publishersBySession.get(ctx.sessionManager)?.update(void 0);
157
+ }
158
+ }
159
+ function setSyncStatus(ctx, value, presentation) {
160
+ if (!ctx.hasUI || value !== void 0 && enabledBySession.get(ctx.sessionManager) === false) return;
161
+ ctx.ui.setStatus(STATUS_KEY, value);
162
+ publishersBySession.get(ctx.sessionManager)?.update(value, presentation);
163
+ }
164
+
165
+ export {
166
+ syncStatusFailureReason,
167
+ createSyncStatusPublisher,
168
+ configureSyncStatus,
169
+ setSyncStatus
170
+ };
171
+ //# sourceMappingURL=chunk-YIPK23JW.ts.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/ui/sync-status.ts"],
4
+ "sourcesContent": ["import type { ExtensionAPI, ExtensionContext } from \"@earendil-works/pi-coding-agent\";\nimport type { ContinuousErrorKind } from \"../sync/continuous-errors.js\";\n\nconst STATUS_KEY = \"sync\";\n\ntype SyncStatusContext = Pick<ExtensionContext, \"hasUI\" | \"sessionManager\" | \"ui\">;\n\nexport type SyncStatusPresentation =\n | {\n activity:\n | \"idle\"\n | \"checking\"\n | \"working\"\n | \"pushing\"\n | \"pulling\"\n | \"resolving\"\n | \"local-change\"\n | \"remote-change\"\n | \"review\";\n reason?: never;\n }\n | { activity: \"retry\" | \"blocked\"; reason: SyncStatusReason };\n\ntype SyncStatusReason =\n | \"temp\"\n | \"busy\"\n | \"stale\"\n | \"auth\"\n | \"storage\"\n | \"review\"\n | \"model\"\n | \"limit\"\n | \"unknown\"\n | \"repair\";\n\nconst failureReasons: Record<ContinuousErrorKind, SyncStatusReason> = {\n transient: \"temp\",\n contention: \"busy\",\n stale: \"stale\",\n authentication: \"auth\",\n storage: \"storage\",\n unsafe: \"review\",\n model: \"model\",\n budget: \"limit\",\n unknown: \"unknown\",\n};\n\nexport function syncStatusFailureReason(kind: ContinuousErrorKind | undefined): SyncStatusReason {\n return typeof kind === \"string\" && Object.hasOwn(failureReasons, kind) ? failureReasons[kind] : \"unknown\";\n}\n\nconst enabledBySession = new WeakMap<ExtensionContext[\"sessionManager\"], boolean>();\nconst publishersBySession = new WeakMap<ExtensionContext[\"sessionManager\"], StatusBinding>();\n\ninterface StatusBinding {\n update(value: string | undefined, presentation?: SyncStatusPresentation): void;\n release(): void;\n}\n\nfunction statusPresentation(presentation: SyncStatusPresentation | undefined): SyncStatusPresentation | undefined {\n if (!presentation) return;\n try {\n const { activity, reason } = presentation;\n if (activity === \"retry\" || activity === \"blocked\") {\n if (typeof reason === \"string\" && /^[a-z][a-z0-9-]{0,31}$/u.exec(reason)?.[0] === reason)\n return { activity, reason };\n } else if (\n [\n \"idle\",\n \"checking\",\n \"working\",\n \"pushing\",\n \"pulling\",\n \"resolving\",\n \"local-change\",\n \"remote-change\",\n \"review\",\n ].includes(activity) &&\n reason === undefined\n ) {\n return { activity };\n }\n } catch {\n // Invalid optional annotations withdraw metadata, not the readable status.\n }\n return undefined;\n}\n\n/** Optional extension-status v1 publisher; it owns no domain work or captured context. */\nexport function createSyncStatusPublisher(events: ExtensionAPI[\"events\"] | undefined) {\n let active: { sessionManager: ExtensionContext[\"sessionManager\"]; binding: StatusBinding } | undefined;\n let used = false;\n let activation = 0;\n const emit = (payload: object) => {\n try {\n events?.emit(\"extension-status:v1:update\", payload);\n } catch {\n // Optional delivery must not interrupt sync, including on minimal test buses.\n }\n };\n const bind = (ctx: SyncStatusContext): (() => void) => {\n if (!ctx.hasUI || (!active && used) || (active && active.sessionManager !== ctx.sessionManager)) return () => {};\n const { sessionManager } = ctx;\n if (active) {\n return publishersBySession.get(sessionManager) === active.binding ? active.binding.release : () => {};\n }\n const owner = activation;\n // Reserve first use before foreign cleanup can reenter this factory.\n used = true;\n publishersBySession.get(sessionManager)?.release();\n if (activation !== owner || publishersBySession.has(sessionManager)) return () => {};\n let current: ({ value: string } & SyncStatusPresentation) | undefined;\n let revision = 0;\n let unsubscribe: (() => void) | undefined;\n const isCurrent = () => publishersBySession.get(sessionManager) === binding;\n const publish = (requestId?: object) => {\n emit({\n version: 1,\n sessionManager,\n key: STATUS_KEY,\n ...(current ?? { value: undefined }),\n ...(requestId === undefined ? {} : { requestId }),\n });\n };\n const binding: StatusBinding = {\n update(value, presentation) {\n if (!isCurrent()) return;\n const owner = ++revision;\n const safePresentation = statusPresentation(presentation);\n if (!isCurrent() || revision !== owner) return;\n current = value && safePresentation ? { value, ...safePresentation } : undefined;\n publish();\n },\n release() {\n const owned = isCurrent();\n revision++;\n if (owned) {\n publishersBySession.delete(sessionManager);\n current = undefined;\n }\n // Retire before optional callbacks; withdrawal observers cannot revive first-use binding.\n if (active?.binding === binding) active = undefined;\n const stop = unsubscribe;\n unsubscribe = undefined;\n try {\n stop?.();\n } catch {\n // A failing optional unsubscribe cannot stop lifecycle cleanup.\n }\n if (owned && !publishersBySession.has(sessionManager)) publish();\n },\n };\n active = { sessionManager, binding };\n used = true;\n publishersBySession.set(sessionManager, binding);\n try {\n unsubscribe = events?.on(\"extension-status:v1:request\", (payload) => {\n try {\n if (!isCurrent() || !payload || typeof payload !== \"object\" || Array.isArray(payload)) return;\n const {\n version,\n sessionManager: manager,\n requestId,\n } = payload as {\n version?: unknown;\n sessionManager?: unknown;\n requestId?: unknown;\n };\n if (\n !isCurrent() ||\n version !== 1 ||\n manager !== sessionManager ||\n !requestId ||\n typeof requestId !== \"object\"\n )\n return;\n publish(requestId);\n } catch {\n // Malformed requests and optional delivery cannot affect sync.\n }\n });\n } catch {\n // Raw status remains available when optional subscription fails.\n }\n return binding.release;\n };\n return {\n bind,\n start(ctx: SyncStatusContext) {\n const owner = ++activation;\n const { sessionManager } = ctx;\n const previous = publishersBySession.get(sessionManager);\n active?.binding.release();\n if (\n activation !== owner ||\n (publishersBySession.has(sessionManager) && publishersBySession.get(sessionManager) !== previous)\n )\n return () => {};\n // Only an explicit lifecycle start can reactivate a released publisher.\n used = false;\n const release = bind(ctx);\n used = true;\n // A superseded start must not receive the newer activation's cleanup capability.\n return activation === owner ? release : () => {};\n },\n cleanupFor(ctx: SyncStatusContext) {\n return active?.sessionManager === ctx.sessionManager ? active.binding.release : () => {};\n },\n };\n}\n\nexport function configureSyncStatus(ctx: SyncStatusContext, enabled: boolean) {\n enabledBySession.set(ctx.sessionManager, enabled);\n if (!enabled) {\n if (ctx.hasUI) ctx.ui.setStatus(STATUS_KEY, undefined);\n publishersBySession.get(ctx.sessionManager)?.update(undefined);\n }\n}\n\nexport function setSyncStatus(\n ctx: SyncStatusContext,\n value: string | undefined,\n presentation?: SyncStatusPresentation,\n) {\n if (!ctx.hasUI || (value !== undefined && enabledBySession.get(ctx.sessionManager) === false)) return;\n ctx.ui.setStatus(STATUS_KEY, value);\n publishersBySession.get(ctx.sessionManager)?.update(value, presentation);\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["owner"]
7
+ }
@@ -5,7 +5,7 @@ import {
5
5
  } from "./chunk-ECYCNZOE.ts";
6
6
  import {
7
7
  withAgentSyncLock
8
- } from "./chunk-ZC3IHFNM.ts";
8
+ } from "./chunk-WQMYV4DW.ts";
9
9
  import "./chunk-3ST7RSYN.ts";
10
10
  import {
11
11
  syncErrorGuidance
@@ -13,7 +13,7 @@ import {
13
13
  import {
14
14
  observationMatchesConfig,
15
15
  syncAttentionMatchesConfig
16
- } from "./chunk-Q23JJW7E.ts";
16
+ } from "./chunk-MW6KUQYA.ts";
17
17
  import {
18
18
  parseOptions,
19
19
  resolveSyncCommand,
@@ -27,7 +27,7 @@ import {
27
27
  } from "./chunk-AMJRUXFT.ts";
28
28
  import {
29
29
  setSyncStatus
30
- } from "./chunk-K3RIEL6J.ts";
30
+ } from "./chunk-YIPK23JW.ts";
31
31
  import {
32
32
  SetupPullRequiresUiError,
33
33
  errorMessage,
@@ -414,7 +414,7 @@ async function handleCommand(rawArgs, ctx, sessionSignal, loaders, attention, on
414
414
  };
415
415
  if (!rawArgs.trim()) {
416
416
  try {
417
- const { showSyncManager } = await import("./manager-ui-INVMAFEN.ts");
417
+ const { showSyncManager } = await import("./manager-ui-FMZXKPX2.ts");
418
418
  if (sessionSignal.aborted) return;
419
419
  await showSyncManager(ctx, run, sessionSignal, {
420
420
  getAttention: () => attention.current(),
@@ -514,7 +514,7 @@ function directSelectionOrigin(rawArgs) {
514
514
  async function resolveSelectionAttention(ctx, attention, signal, loaders, options = {}) {
515
515
  const current = attention.current();
516
516
  if (!current || signal.aborted) return;
517
- const { dispatchManagerResult } = await import("./manager-result-dispatcher-6W52NM7F.ts");
517
+ const { dispatchManagerResult } = await import("./manager-result-dispatcher-XCYPW7RC.ts");
518
518
  if (signal.aborted || attention.current() !== current) return;
519
519
  await dispatchManagerResult(
520
520
  ctx,
@@ -545,4 +545,4 @@ export {
545
545
  handleCommand,
546
546
  resolveSelectionAttention
547
547
  };
548
- //# sourceMappingURL=command-handler-VKLZBRLO.ts.map
548
+ //# sourceMappingURL=command-handler-KCB6MCWS.ts.map
@@ -18,7 +18,7 @@ import {
18
18
  import "./chunk-TZC7GDJE.ts";
19
19
  import {
20
20
  withAgentSyncLock
21
- } from "./chunk-ZC3IHFNM.ts";
21
+ } from "./chunk-WQMYV4DW.ts";
22
22
  import "./chunk-3ST7RSYN.ts";
23
23
  import "./chunk-FLHCOJCD.ts";
24
24
  import "./chunk-MKSMJPVA.ts";
@@ -29,8 +29,9 @@ import {
29
29
  captureMutationOwner
30
30
  } from "./chunk-GNYGNHFF.ts";
31
31
  import {
32
- setSyncStatus
33
- } from "./chunk-K3RIEL6J.ts";
32
+ setSyncStatus,
33
+ syncStatusFailureReason
34
+ } from "./chunk-YIPK23JW.ts";
34
35
  import {
35
36
  loadConfigForCheck,
36
37
  syncCheckConfigFingerprint
@@ -168,7 +169,10 @@ function createContinuousSync(loaders, clock = systemClock, publish) {
168
169
  if (signal.aborted) return;
169
170
  try {
170
171
  validateContext();
171
- setSyncStatus(ctx, "sync blocked: private state or settings need repair");
172
+ setSyncStatus(ctx, "sync blocked: private state or settings need repair", {
173
+ activity: "blocked",
174
+ reason: "repair"
175
+ });
172
176
  if (!repairNotices.has(ctx.sessionManager)) {
173
177
  repairNotices.add(ctx.sessionManager);
174
178
  ctx.ui.notify(
@@ -219,7 +223,7 @@ function createContinuousSync(loaders, clock = systemClock, publish) {
219
223
  if (lease) {
220
224
  await monitor(ctx, config, binding, lease, signal, explicitRetry, startup);
221
225
  explicitRetry = false;
222
- } else setSyncStatus(ctx, "sync waiting: another local owner");
226
+ } else setSyncStatus(ctx, "sync waiting: another local owner", { activity: "idle" });
223
227
  } finally {
224
228
  await lease?.release();
225
229
  }
@@ -228,7 +232,10 @@ function createContinuousSync(loaders, clock = systemClock, publish) {
228
232
  if (signal.aborted) return;
229
233
  const failure = continuousFailure(error);
230
234
  if (!failure.retry && !(error instanceof Error && error.name === "AbortError")) throw error;
231
- setSyncStatus(ctx, `sync retry scheduled: ${failure.kind}`);
235
+ setSyncStatus(ctx, `sync retry scheduled: ${failure.kind}`, {
236
+ activity: "retry",
237
+ reason: syncStatusFailureReason(failure.kind)
238
+ });
232
239
  }
233
240
  validateOwner();
234
241
  if (!continuousEnabled(await loadConfigForCheck())) return;
@@ -404,7 +411,8 @@ function createContinuousSync(loaders, clock = systemClock, publish) {
404
411
  validate();
405
412
  setSyncStatus(
406
413
  ctx,
407
- state.phase === "blocked" ? `sync blocked: ${state.error}` : state.phase === "retry" ? `sync retry scheduled: ${state.error}` : "sync waiting for changes"
414
+ state.phase === "blocked" ? `sync blocked: ${state.error}` : state.phase === "retry" ? `sync retry scheduled: ${state.error}` : "sync waiting for changes",
415
+ state.phase === "blocked" || state.phase === "retry" ? { activity: state.phase, reason: syncStatusFailureReason(state.error) } : { activity: "idle" }
408
416
  );
409
417
  if (state.phase === "retry") pollDue = Math.min(pollDue, state.next);
410
418
  const next = Math.max(
@@ -433,7 +441,7 @@ function createContinuousSync(loaders, clock = systemClock, publish) {
433
441
  validate();
434
442
  if (!force && !pending && current.phase === "blocked" && ["authentication", "storage", "unknown"].includes(current.error ?? ""))
435
443
  return;
436
- setSyncStatus(ctx, "sync checking");
444
+ setSyncStatus(ctx, "sync checking", { activity: "checking" });
437
445
  const inspectionModule = await timings.measure("inspection import", () => loaders.inspection());
438
446
  validate();
439
447
  const observed = await timings.measure(
@@ -495,7 +503,7 @@ function createContinuousSync(loaders, clock = systemClock, publish) {
495
503
  if (observed.journal || observed.inspection.localChanged || observed.inspection.remoteChanged) {
496
504
  const operations = await timings.measure("operations import", () => loaders.operations());
497
505
  validate();
498
- setSyncStatus(ctx, "sync syncing");
506
+ setSyncStatus(ctx, "sync syncing", { activity: "working" });
499
507
  const result = await timings.measure(
500
508
  "automatic transfer",
501
509
  () => withStateDirectoryAccess(
@@ -574,4 +582,4 @@ export {
574
582
  continuousEnabled,
575
583
  createContinuousSync
576
584
  };
577
- //# sourceMappingURL=continuous-sync-TTOSJCQU.ts.map
585
+ //# sourceMappingURL=continuous-sync-FAFNLEUW.ts.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/sync/continuous-watch.ts", "../../src/sync/continuous-sync.ts"],
4
+ "sourcesContent": ["import { type FSWatcher, watch } from \"node:fs\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { getAgentDir } from \"@earendil-works/pi-coding-agent\";\nimport { isDeniedPath } from \"../paths.js\";\nimport type { AnySyncConfig } from \"../settings/settings-types.js\";\n\n/** Hints only. The scheduler's periodic snapshot scan remains required. */\nexport async function watchContinuous(\n config: AnySyncConfig,\n changed: (settings: boolean) => void,\n): Promise<() => void> {\n const root = getAgentDir();\n const watchers: FSWatcher[] = [];\n const selected = config.include.map((item) => path.resolve(root, item));\n const relevant = (target: string) =>\n selected.some(\n (item) => target === item || target.startsWith(`${item}${path.sep}`) || item.startsWith(`${target}${path.sep}`),\n );\n const add = (directory: string, recursive: boolean) => {\n try {\n const watcher = watch(directory, { recursive, persistent: false }, (_event, file) => {\n // Unknown names can be our own private writes. Periodic scans cover them.\n if (!file) return;\n const target = path.resolve(directory, String(file));\n if (target === path.join(root, \"pi-sync.json\")) changed(true);\n else if (isDeniedPath(path.relative(root, target))) return;\n else if (relevant(target)) changed(false);\n });\n watcher.on(\"error\", () => watcher.close());\n watchers.push(watcher);\n } catch {\n /* Periodic scans cover unavailable or unsupported watchers. */\n }\n };\n add(root, false);\n const directories = new Set<string>();\n try {\n for (const target of selected) {\n try {\n const stat = await fs.lstat(target);\n if (stat.isSymbolicLink()) continue;\n const directory = stat.isDirectory() ? target : path.dirname(target);\n if (directory === root || directories.has(directory)) continue;\n directories.add(directory);\n add(directory, stat.isDirectory());\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") continue;\n // Missing targets are found by the parent hint or the next periodic scan.\n }\n }\n return () => {\n for (const watcher of watchers) watcher.close();\n };\n } catch (error) {\n for (const watcher of watchers) watcher.close();\n throw error;\n }\n}\n", "import type { ExtensionContext } from \"@earendil-works/pi-coding-agent\";\nimport { loadConfigForCheck, syncCheckConfigFingerprint } from \"../settings/config.js\";\nimport type { AnySyncConfig } from \"../settings/settings-types.js\";\nimport { snapshotOptionsForContext } from \"../snapshot/session-paths.js\";\nimport { withLock } from \"../state/lock.js\";\nimport { withStateDirectoryAccess } from \"../state/state-directory.js\";\nimport { readStateForConfig } from \"../state/sync-state-store.js\";\nimport { setSyncStatus, syncStatusFailureReason } from \"../ui/sync-status.js\";\nimport { withAgentSyncLock } from \"./agent-sync.js\";\nimport { ContinuousError, continuousFailure } from \"./continuous-errors.js\";\nimport { acquireContinuousLease, type ContinuousLease } from \"./continuous-lease.js\";\nimport {\n normalizeContinuousClock,\n readContinuousRecord,\n reserveContinuousRequest,\n updateContinuousRecord,\n} from \"./continuous-record.js\";\nimport { continuousBinding, hashContinuous } from \"./continuous-storage.js\";\nimport { watchContinuous } from \"./continuous-watch.js\";\nimport { readMergeJournal } from \"./merge-journal.js\";\nimport { createStartupTimings, type StartupTimingPublisher, type StartupTimings } from \"./startup-timings.js\";\nimport type { SyncLoaders } from \"./sync-loaders.js\";\nimport { captureMutationOwner } from \"./sync-local.js\";\nimport { fileHashMap } from \"./sync-state.js\";\n\nexport function continuousEnabled(config: Pick<AnySyncConfig, \"continuous\" | \"agentMode\">) {\n return Boolean(config.continuous && config.agentMode);\n}\nexport interface ContinuousClock {\n now(): number;\n random(): number;\n schedule(ms: number, run: () => void, kind?: \"wait\" | \"authorization\"): () => void;\n}\nconst systemClock: ContinuousClock = {\n now: () => Date.now(),\n random: () => Math.random(),\n schedule: (ms, run) => {\n const timer = setTimeout(run, ms);\n timer.unref?.();\n return () => clearTimeout(timer);\n },\n};\nconst LOCAL_CHECK_MS = 5_000;\nconst POLL_MS = 60_000;\nconst DEBOUNCE_MS = 1_000;\n\ninterface ContinuousStartup {\n signal: AbortSignal;\n debug: boolean;\n reported: boolean;\n}\n\n/** Created on first enabled session. No module/factory-owned timers or watchers. */\nexport function createContinuousSync(\n loaders: SyncLoaders,\n clock: ContinuousClock = systemClock,\n publish?: StartupTimingPublisher,\n) {\n const startups = new WeakMap<ExtensionContext[\"sessionManager\"], ContinuousStartup>();\n const repairNotices = new WeakSet<ExtensionContext[\"sessionManager\"]>();\n let task:\n | { owner: ExtensionContext[\"sessionManager\"]; controller: AbortController; promise: Promise<void>; clear(): void }\n | undefined;\n return {\n start(ctx: ExtensionContext, sessionSignal: AbortSignal, explicitRetry = false, debug = false) {\n if (!ctx.hasUI || (ctx.mode !== \"tui\" && ctx.mode !== \"rpc\") || sessionSignal.aborted || task) return;\n const controller = new AbortController();\n const signal = AbortSignal.any([sessionSignal, controller.signal]);\n const validateContext = captureMutationOwner(ctx);\n // The caller supplies the session-start debug value, including first activation after settings edits.\n const previousStartup = startups.get(ctx.sessionManager);\n const startup: ContinuousStartup =\n previousStartup?.signal === sessionSignal ? previousStartup : { signal: sessionSignal, debug, reported: false };\n startups.set(ctx.sessionManager, startup);\n const current = {\n owner: ctx.sessionManager,\n controller,\n promise: Promise.resolve(),\n clear: () => {\n try {\n validateContext();\n setSyncStatus(ctx, undefined);\n } catch {\n /* replaced session */\n }\n },\n };\n task = current;\n current.promise = (async () => {\n let explicit = explicitRetry;\n while (!signal.aborted) {\n try {\n await run(ctx, signal, explicit, startup);\n return;\n } catch {\n if (signal.aborted) return;\n try {\n validateContext();\n setSyncStatus(ctx, \"sync blocked: private state or settings need repair\", {\n activity: \"blocked\",\n reason: \"repair\",\n });\n if (!repairNotices.has(ctx.sessionManager)) {\n repairNotices.add(ctx.sessionManager);\n ctx.ui.notify(\n \"Continuous sync blocked: private state or settings need repair. Use /sync. Evidence was retained.\",\n \"warning\",\n );\n }\n } catch {\n return;\n }\n }\n explicit = false;\n // Only local prerequisites are retried here. No remote/model request can\n // pass a malformed settings/state read. A repair can resume monitoring.\n await wait(clock, LOCAL_CHECK_MS, signal);\n }\n })()\n .catch(() => {\n /* Cancellation/UI disposal must not leak a detached rejection. */\n })\n .finally(() => {\n if (task === current) task = undefined;\n });\n },\n async stop(owner?: ExtensionContext[\"sessionManager\"]) {\n const current = task;\n if (!current || (owner && current.owner !== owner)) return;\n current.controller.abort(new DOMException(\"Continuous sync interrupted\", \"AbortError\"));\n current.clear();\n await current.promise;\n },\n };\n\n async function run(ctx: ExtensionContext, signal: AbortSignal, explicitRetry: boolean, startup: ContinuousStartup) {\n const validateOwner = captureMutationOwner(ctx, signal);\n try {\n while (!signal.aborted) {\n validateOwner();\n const config = await loadConfigForCheck();\n validateOwner();\n if (!continuousEnabled(config)) return;\n try {\n if (ctx.isIdle()) {\n let lease: ContinuousLease | undefined;\n let binding = \"\";\n try {\n await withStateDirectoryAccess(async () => {\n validateOwner();\n binding = await continuousBinding(config);\n validateOwner();\n lease = await acquireContinuousLease(binding);\n validateOwner();\n });\n if (lease) {\n await monitor(ctx, config, binding, lease, signal, explicitRetry, startup);\n explicitRetry = false;\n } else setSyncStatus(ctx, \"sync waiting: another local owner\", { activity: \"idle\" });\n } finally {\n await lease?.release();\n }\n }\n } catch (error) {\n if (signal.aborted) return;\n const failure = continuousFailure(error);\n if (!failure.retry && !(error instanceof Error && error.name === \"AbortError\")) throw error;\n setSyncStatus(ctx, `sync retry scheduled: ${failure.kind}`, {\n activity: \"retry\",\n reason: syncStatusFailureReason(failure.kind),\n });\n }\n validateOwner();\n if (!continuousEnabled(await loadConfigForCheck())) return;\n validateOwner();\n await wait(clock, LOCAL_CHECK_MS, signal);\n }\n } finally {\n // Shutdown/replacement owns clearing the old UI; do not call it from a stale continuation.\n if (!signal.aborted) {\n try {\n validateOwner();\n setSyncStatus(ctx, undefined);\n } catch {\n /* stale context */\n }\n }\n }\n }\n\n async function monitor(\n ctx: ExtensionContext,\n initial: AnySyncConfig,\n binding: string,\n lease: ContinuousLease,\n parent: AbortSignal,\n explicitRetry: boolean,\n startup: ContinuousStartup,\n ) {\n const signal = AbortSignal.any([parent, lease.signal]);\n const validateOwner = captureMutationOwner(ctx, signal);\n let config = initial;\n let closeWatch = () => {};\n let wake = () => {};\n let dirtyAt: number | undefined;\n let cycle: AbortController | undefined;\n const changed = (settings: boolean) => {\n dirtyAt = clock.now();\n if (settings) cycle?.abort(new DOMException(\"Continuous settings changed\", \"AbortError\"));\n wake();\n };\n const validate = () => {\n validateOwner();\n lease.assert();\n if (!ctx.isIdle()) throw new DOMException(\"Owning session became busy\", \"AbortError\");\n };\n const stopWatch = () => {\n closeWatch();\n wake();\n };\n signal.addEventListener(\"abort\", stopWatch, { once: true });\n let pollDue = 0;\n try {\n closeWatch = await watchContinuous(config, changed);\n validate();\n while (!signal.aborted && ctx.isIdle()) {\n validate();\n const latest = await loadConfigForCheck();\n validate();\n if (!continuousEnabled(latest) || (await continuousBinding(latest)) !== binding) return;\n validate();\n if (syncCheckConfigFingerprint(latest) !== syncCheckConfigFingerprint(config)) {\n closeWatch();\n config = latest;\n closeWatch = await watchContinuous(config, changed);\n validate();\n pollDue = 0;\n }\n const record = await readContinuousRecord(binding);\n validate();\n const now = clock.now();\n const oldClock = JSON.stringify([record.next, record.calls]);\n normalizeContinuousClock(record, now);\n if (oldClock !== JSON.stringify([record.next, record.calls])) {\n await updateContinuousRecord(binding, lease, (current) => normalizeContinuousClock(current, now));\n validate();\n }\n const configuration = hashContinuous([{ ...config, showStatus: undefined, debug: undefined }, ctx.model]);\n const controlChanged = record.configuration !== configuration;\n if (controlChanged || explicitRetry) {\n record.next = 0;\n pollDue = 0;\n }\n const hintDue = dirtyAt === undefined ? Number.POSITIVE_INFINITY : dirtyAt + DEBOUNCE_MS;\n const due = Math.max(record.error === \"budget\" ? 0 : record.next, Math.min(pollDue, hintDue));\n if (now >= due) {\n const timings = createStartupTimings(publish);\n const report = !startup.reported && startup.debug;\n startup.reported = true;\n let outcome: \"completed\" | \"stopped\" = \"stopped\";\n const force = explicitRetry || controlChanged;\n explicitRetry = false;\n const expectedModel = hashContinuous(ctx.model);\n const expectedConfig = syncCheckConfigFingerprint(config);\n dirtyAt = undefined;\n cycle = new AbortController();\n const cancelDeadline = clock.schedule(30_000, () =>\n cycle?.abort(new DOMException(\"Continuous cycle timed out\", \"TimeoutError\")),\n );\n const guard = new AbortController();\n const guardSignal = AbortSignal.any([signal, cycle.signal, guard.signal]);\n const activeCycle = cycle;\n // Transfer entrypoints supply each fresh settings read. Never let a new\n // transfer adopt authorization that changed after this cycle's inspection.\n const validateCycle = (latest?: AnySyncConfig) => {\n validate();\n if (\n (latest && syncCheckConfigFingerprint(latest) !== expectedConfig) ||\n hashContinuous(ctx.model) !== expectedModel\n )\n activeCycle.abort(new DOMException(\"Continuous authorization changed\", \"AbortError\"));\n activeCycle.signal.throwIfAborted();\n };\n const guardTask = (async () => {\n while (!guardSignal.aborted) {\n await wait(clock, LOCAL_CHECK_MS, guardSignal, undefined, \"authorization\");\n if (guardSignal.aborted) return;\n try {\n validate();\n const latest = await loadConfigForCheck();\n if (guardSignal.aborted) return;\n validateCycle(latest);\n } catch {\n activeCycle.abort(new DOMException(\"Continuous authorization unavailable\", \"AbortError\"));\n }\n }\n })().catch(() => {});\n try {\n await performCycle(\n ctx,\n config,\n binding,\n lease,\n AbortSignal.any([signal, cycle.signal]),\n validateCycle,\n configuration,\n force,\n timings,\n );\n outcome = \"completed\";\n } catch (error) {\n if (signal.aborted || !ctx.isIdle()) return;\n // A settings hint interrupts the old authorization; load it afresh, not as a failed transfer.\n if (cycle.signal.aborted && cycle.signal.reason?.name !== \"TimeoutError\") {\n pollDue = 0;\n continue;\n }\n const failure = continuousFailure(error);\n let announce = false;\n await updateContinuousRecord(binding, lease, (current) => {\n const now = clock.now();\n normalizeContinuousClock(current, now);\n const notice = hashContinuous([failure.kind, current.evidence, configuration]);\n announce = current.notice !== notice;\n if (!failure.retry) current.notice = notice;\n current.configuration = configuration;\n current.pending = true;\n current.error = failure.kind;\n current.phase = failure.retry ? \"retry\" : \"blocked\";\n current.failures = Math.min(30, current.failures + 1);\n const base = Math.min(300_000, 5_000 * 2 ** Math.min(6, current.failures - 1));\n const delay = Math.min(300_000, base + Math.floor(clock.random() * base * 0.2));\n current.next = now + Math.max(delay, failure.delay ?? 0);\n });\n validate();\n if (announce && !failure.retry)\n ctx.ui.notify(\n `Continuous sync blocked (${failure.kind}). Review /sync or repair the setup. Evidence was retained.`,\n \"warning\",\n );\n } finally {\n cancelDeadline();\n guard.abort();\n await guardTask;\n cycle = undefined;\n timings.publish(ctx, report, signal, \"continuous startup\", outcome);\n }\n pollDue = clock.now() + POLL_MS + Math.floor(clock.random() * 6_000);\n closeWatch();\n closeWatch = () => {};\n closeWatch = await watchContinuous(config, changed);\n validate();\n }\n validate();\n const state = await readContinuousRecord(binding);\n validate();\n setSyncStatus(\n ctx,\n state.phase === \"blocked\"\n ? `sync blocked: ${state.error}`\n : state.phase === \"retry\"\n ? `sync retry scheduled: ${state.error}`\n : \"sync waiting for changes\",\n state.phase === \"blocked\" || state.phase === \"retry\"\n ? { activity: state.phase, reason: syncStatusFailureReason(state.error) }\n : { activity: \"idle\" },\n );\n if (state.phase === \"retry\") pollDue = Math.min(pollDue, state.next);\n const next = Math.max(\n state.error === \"budget\" ? 0 : state.next,\n Math.min(pollDue, dirtyAt === undefined ? Number.POSITIVE_INFINITY : dirtyAt + DEBOUNCE_MS),\n );\n await wait(clock, Math.max(1, Math.min(LOCAL_CHECK_MS, next - clock.now())), signal, (callback) => {\n wake = callback;\n });\n }\n } finally {\n signal.removeEventListener(\"abort\", stopWatch);\n closeWatch();\n cycle?.abort();\n }\n }\n\n async function performCycle(\n ctx: ExtensionContext,\n config: AnySyncConfig,\n binding: string,\n lease: ContinuousLease,\n signal: AbortSignal,\n validateOwner: (config?: AnySyncConfig) => void,\n configuration: string,\n force: boolean,\n timings: StartupTimings,\n ) {\n const validate = (latest?: AnySyncConfig) => {\n signal.throwIfAborted();\n validateOwner(latest);\n };\n validate();\n const current = await readContinuousRecord(binding);\n validate();\n // A newly pending journal may prove an uncertain commit. It is never authority to republish.\n const pending = await guardedLock(\"continuous-journal\", () => readMergeJournal(config));\n validate();\n if (\n !force &&\n !pending &&\n current.phase === \"blocked\" &&\n [\"authentication\", \"storage\", \"unknown\"].includes(current.error ?? \"\")\n )\n return;\n setSyncStatus(ctx, \"sync checking\", { activity: \"checking\" });\n const inspectionModule = await timings.measure(\"inspection import\", () => loaders.inspection());\n validate();\n const observed = await timings.measure(\"inspection and guards\", () =>\n guardedLock(\"continuous-check\", async () => {\n validate();\n const inspection = await inspectionModule.inspectSync(\n config,\n snapshotOptionsForContext(ctx, config),\n signal,\n undefined,\n timings,\n );\n validate();\n let localIdentity = inspection.localIdentity;\n if (!localIdentity) {\n const snapshotModule = await loaders.snapshot();\n validate();\n const local = await snapshotModule.createSnapshot(config.snapshotIdentity, {\n ...snapshotOptionsForContext(ctx, config),\n signal,\n });\n validate();\n localIdentity = hashContinuous(fileHashMap(local));\n }\n const journal = await readMergeJournal(config);\n validate();\n return { inspection, journal, localIdentity };\n }),\n );\n validate();\n const evidence = hashContinuous([\n configuration,\n observed.localIdentity,\n observed.inspection.head?.revision,\n observed.inspection.stateIdentity,\n ]);\n const recovery = observed.journal ? hashContinuous([evidence, observed.journal]) : undefined;\n const blocked =\n !force &&\n current.evidence === evidence &&\n ((current.phase === \"blocked\" && (!recovery || recovery === current.recovery)) ||\n (current.error === \"budget\" && current.next > clock.now() && !observed.journal));\n await updateContinuousRecord(binding, lease, (record) => {\n if (record.configuration !== configuration) {\n record.failures = 0;\n record.next = 0;\n }\n record.configuration = configuration;\n record.checked = clock.now();\n record.evidence = evidence;\n if (!blocked) {\n if (record.phase !== \"blocked\") record.phase = \"syncing\";\n record.pending = true;\n if (recovery) record.recovery = recovery;\n }\n });\n validate();\n if (blocked) return;\n if (\n !observed.journal &&\n (observed.inspection.firstSync ||\n !observed.inspection.head ||\n observed.inspection.selectionState?.kind !== \"same\")\n )\n throw new ContinuousError(\"unsafe\", \"Continuous sync needs an accepted baseline and matching remote selection.\");\n let transferred = false;\n if (observed.journal || observed.inspection.localChanged || observed.inspection.remoteChanged) {\n const operations = await timings.measure(\"operations import\", () => loaders.operations());\n validate();\n setSyncStatus(ctx, \"sync syncing\", { activity: \"working\" });\n const result = await timings.measure(\"automatic transfer\", () =>\n withStateDirectoryAccess(() =>\n withAgentSyncLock(\n ctx,\n {\n args: [],\n yes: true,\n force: false,\n stale: false,\n silent: true,\n reload: false,\n auto: true,\n signal,\n startupTimings: timings,\n background: {\n validate,\n reserve: (key, requestSignal) =>\n reserveContinuousRequest(binding, lease, key, () => clock.now(), requestSignal),\n },\n },\n (options) => operations.syncBoth(ctx, options),\n ),\n ),\n );\n validate();\n transferred = result === \"applied\";\n }\n const state = await guardedLock(\"continuous-result\", () => readStateForConfig(config));\n validate();\n const unresolved = state.unresolved;\n let announcePartial = false;\n await updateContinuousRecord(binding, lease, (record) => {\n record.phase = unresolved?.length ? \"blocked\" : \"waiting\";\n record.pending = Boolean(unresolved?.length);\n record.failures = 0;\n record.next = 0;\n if (unresolved?.length) {\n record.error = \"unsafe\";\n const notice = hashContinuous([\"partial\", unresolved, configuration]);\n announcePartial = record.notice !== notice;\n record.notice = notice;\n } else {\n delete record.error;\n delete record.notice;\n }\n if (transferred) record.transferred = clock.now();\n });\n validate();\n if (announcePartial)\n ctx.ui.notify(\n \"Continuous sync retained unresolved groups. Review /sync conflicts; independent partial progress was preserved.\",\n \"warning\",\n );\n }\n}\n\nfunction guardedLock<T>(command: string, run: () => Promise<T>) {\n return withStateDirectoryAccess(() => withLock(command, run));\n}\n\nfunction wait(\n clock: ContinuousClock,\n ms: number,\n signal: AbortSignal,\n expose?: (wake: () => void) => void,\n kind: \"wait\" | \"authorization\" = \"wait\",\n) {\n signal.throwIfAborted();\n return new Promise<void>((resolve) => {\n const done = () => {\n cancel();\n signal.removeEventListener(\"abort\", done);\n expose?.(() => {});\n resolve();\n };\n const cancel = clock.schedule(ms, done, kind);\n signal.addEventListener(\"abort\", done, { once: true });\n expose?.(done);\n if (signal.aborted) done();\n });\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["latest", "now"]
7
+ }
@@ -2,8 +2,8 @@
2
2
  // @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
3
3
  import {
4
4
  dispatchManagerResult
5
- } from "./chunk-ZDDBZH72.ts";
6
- import "./chunk-OKPPZA4D.ts";
5
+ } from "./chunk-JYILGR3K.ts";
6
+ import "./chunk-MG66XM5U.ts";
7
7
  import "./chunk-TIMWN2RH.ts";
8
8
  import "./chunk-OJARL2TG.ts";
9
9
  import "./chunk-TZC7GDJE.ts";
@@ -12,7 +12,7 @@ import "./chunk-FLHCOJCD.ts";
12
12
  import "./chunk-MKSMJPVA.ts";
13
13
  import "./chunk-GNYGNHFF.ts";
14
14
  import "./chunk-AMJRUXFT.ts";
15
- import "./chunk-K3RIEL6J.ts";
15
+ import "./chunk-YIPK23JW.ts";
16
16
  import "./chunk-7D5SF7P3.ts";
17
17
  import "./chunk-OVBAW7KV.ts";
18
18
  import "./chunk-X7R6DCVF.ts";
@@ -29,4 +29,4 @@ import "./chunk-FHE2DCA2.ts";
29
29
  export {
30
30
  dispatchManagerResult
31
31
  };
32
- //# sourceMappingURL=manager-result-dispatcher-6W52NM7F.ts.map
32
+ //# sourceMappingURL=manager-result-dispatcher-XCYPW7RC.ts.map
@@ -32,10 +32,10 @@ import {
32
32
  } from "./chunk-ECYCNZOE.ts";
33
33
  import {
34
34
  dispatchManagerResult
35
- } from "./chunk-ZDDBZH72.ts";
35
+ } from "./chunk-JYILGR3K.ts";
36
36
  import {
37
37
  runCancellableOperation
38
- } from "./chunk-OKPPZA4D.ts";
38
+ } from "./chunk-MG66XM5U.ts";
39
39
  import "./chunk-TIMWN2RH.ts";
40
40
  import "./chunk-OJARL2TG.ts";
41
41
  import {
@@ -60,7 +60,7 @@ import {
60
60
  observationMatchesConfig,
61
61
  observationSummary,
62
62
  syncAttentionMatchesConfig
63
- } from "./chunk-Q23JJW7E.ts";
63
+ } from "./chunk-MW6KUQYA.ts";
64
64
  import {
65
65
  AUTOMATIC_SYNC_DESCRIPTION,
66
66
  STARTUP_TRANSFER_DESCRIPTION,
@@ -74,7 +74,7 @@ import {
74
74
  } from "./chunk-AMJRUXFT.ts";
75
75
  import {
76
76
  configureSyncStatus
77
- } from "./chunk-K3RIEL6J.ts";
77
+ } from "./chunk-YIPK23JW.ts";
78
78
  import {
79
79
  errorMessage
80
80
  } from "./chunk-7D5SF7P3.ts";
@@ -190,7 +190,7 @@ function blockedSyncMenuItem(label, manager) {
190
190
  };
191
191
  }
192
192
  async function showManagerAttention(ctx, attention, runRoute, signal, onSelectionResolved) {
193
- const { showRemoteSelectionReview } = await import("./remote-selection-ui-TD4C4W3J.ts");
193
+ const { showRemoteSelectionReview } = await import("./remote-selection-ui-MYM2YCPF.ts");
194
194
  if (signal?.aborted) return "close";
195
195
  const review = await showRemoteSelectionReview(ctx, attention.decision.setupName, signal, void 0, {
196
196
  decision: attention.decision,
@@ -1774,7 +1774,7 @@ async function showSyncSettings(ctx, runRoute, signal, reviewedSetup) {
1774
1774
  },
1775
1775
  "remote-include": async ({ signal: actionSignal }) => {
1776
1776
  const reviewSignal = signal ? AbortSignal.any([signal, actionSignal]) : actionSignal;
1777
- const { showRemoteSelectionReview } = await import("./remote-selection-ui-TD4C4W3J.ts");
1777
+ const { showRemoteSelectionReview } = await import("./remote-selection-ui-MYM2YCPF.ts");
1778
1778
  if (reviewSignal.aborted) return { kind: "rejected" };
1779
1779
  const review = await showRemoteSelectionReview(ctx, setupName, reviewSignal, void 0, {
1780
1780
  origin: "settings",
@@ -1879,7 +1879,7 @@ async function showSyncManager(ctx, runRoute, sessionSignal, options = {}) {
1879
1879
  if (!attention) {
1880
1880
  const observation = state.manager.observation;
1881
1881
  if (!observation) return { kind: "stay" };
1882
- const { showRemoteSelectionReview } = await import("./remote-selection-ui-TD4C4W3J.ts");
1882
+ const { showRemoteSelectionReview } = await import("./remote-selection-ui-MYM2YCPF.ts");
1883
1883
  if (sessionSignal?.aborted) return { kind: "close" };
1884
1884
  const config = await loadConfig();
1885
1885
  if (sessionSignal?.aborted) return { kind: "close" };
@@ -2158,4 +2158,4 @@ function syncMainMenuItem(label) {
2158
2158
  export {
2159
2159
  showSyncManager
2160
2160
  };
2161
- //# sourceMappingURL=manager-ui-INVMAFEN.ts.map
2161
+ //# sourceMappingURL=manager-ui-FMZXKPX2.ts.map
@@ -2,7 +2,7 @@
2
2
  // @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
3
3
  import {
4
4
  showRemoteSelectionReview
5
- } from "./chunk-OKPPZA4D.ts";
5
+ } from "./chunk-MG66XM5U.ts";
6
6
  import "./chunk-TIMWN2RH.ts";
7
7
  import "./chunk-OJARL2TG.ts";
8
8
  import "./chunk-TZC7GDJE.ts";
@@ -11,7 +11,7 @@ import "./chunk-FLHCOJCD.ts";
11
11
  import "./chunk-MKSMJPVA.ts";
12
12
  import "./chunk-GNYGNHFF.ts";
13
13
  import "./chunk-AMJRUXFT.ts";
14
- import "./chunk-K3RIEL6J.ts";
14
+ import "./chunk-YIPK23JW.ts";
15
15
  import "./chunk-7D5SF7P3.ts";
16
16
  import "./chunk-OVBAW7KV.ts";
17
17
  import "./chunk-X7R6DCVF.ts";
@@ -28,4 +28,4 @@ import "./chunk-FHE2DCA2.ts";
28
28
  export {
29
29
  showRemoteSelectionReview
30
30
  };
31
- //# sourceMappingURL=remote-selection-ui-TD4C4W3J.ts.map
31
+ //# sourceMappingURL=remote-selection-ui-MYM2YCPF.ts.map
@@ -67,7 +67,7 @@ import {
67
67
  } from "./chunk-AMJRUXFT.ts";
68
68
  import {
69
69
  setSyncStatus
70
- } from "./chunk-K3RIEL6J.ts";
70
+ } from "./chunk-YIPK23JW.ts";
71
71
  import {
72
72
  errorMessage
73
73
  } from "./chunk-7D5SF7P3.ts";
@@ -259,7 +259,7 @@ async function push(ctx, options, input, factory = createSyncBackend) {
259
259
  const state = input?.state ?? await readStateForConfig(config);
260
260
  validateMutation();
261
261
  requireResolvedDirectionalProgress(state, options);
262
- setSyncStatus(ctx, `pushing ${config.setupName}`);
262
+ setSyncStatus(ctx, `pushing ${config.setupName}`, { activity: "pushing" });
263
263
  const backend = input?.backend ?? await factory(config);
264
264
  throwIfAborted(options.signal);
265
265
  const localRaw = input?.local ?? await createSnapshot(config.snapshotIdentity, snapshotOptionsForContext(ctx, config));
@@ -391,7 +391,7 @@ async function pull(ctx, options, factory = createSyncBackend) {
391
391
  const config = await loadConfig(options.setup);
392
392
  throwIfAborted(options.signal);
393
393
  await requireNoMergeJournal(config, options);
394
- setSyncStatus(ctx, `pulling ${config.setupName}`);
394
+ setSyncStatus(ctx, `pulling ${config.setupName}`, { activity: "pulling" });
395
395
  const backend = await factory(config);
396
396
  const state = await readStateForConfig(config);
397
397
  validateMutation();
@@ -816,7 +816,7 @@ var DEFAULT_PROFILE = "default";
816
816
  async function status(ctx, options, factory = createSyncBackend) {
817
817
  const config = await loadConfig(options.setup);
818
818
  throwIfAborted(options.signal);
819
- setSyncStatus(ctx, `checking ${config.setupName}`);
819
+ setSyncStatus(ctx, `checking ${config.setupName}`, { activity: "checking" });
820
820
  const { head, selectionState, localChanged, remoteChanged, localFiles, destination, capability } = await inspectSync(
821
821
  config,
822
822
  snapshotOptionsForContext(ctx, config),
@@ -851,7 +851,7 @@ async function status(ctx, options, factory = createSyncBackend) {
851
851
  async function diff(ctx, options, factory = createSyncBackend) {
852
852
  const config = await loadConfig(options.setup);
853
853
  throwIfAborted(options.signal);
854
- setSyncStatus(ctx, `checking ${config.setupName}`);
854
+ setSyncStatus(ctx, `checking ${config.setupName}`, { activity: "checking" });
855
855
  const backend = await factory(config);
856
856
  const local = portableSnapshot(
857
857
  await createSnapshot(config.snapshotIdentity, snapshotOptionsForContext(ctx, config)),
@@ -1018,4 +1018,4 @@ export {
1018
1018
  status,
1019
1019
  syncBoth
1020
1020
  };
1021
- //# sourceMappingURL=sync-operations-TMGQHBF5.ts.map
1021
+ //# sourceMappingURL=sync-operations-45APGOL3.ts.map