@narumitw/pi-sync 0.57.6 → 0.57.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/chunks/{chunk-UZPMDLTL.ts → chunk-M6VQJIOU.ts} +5 -5
- package/dist/chunks/chunk-M6VQJIOU.ts.map +7 -0
- package/dist/chunks/{chunk-R75IHAOJ.ts → chunk-N5TFMPB5.ts} +2 -2
- package/dist/chunks/{chunk-DT6TOCIG.ts → chunk-PQW6GS4J.ts} +2 -2
- package/dist/chunks/{conflict-review-T7GSOKNG.ts → conflict-review-UC5AGVER.ts} +3 -3
- package/dist/chunks/{continuous-sync-U4HIKPQK.ts → continuous-sync-POEQXR25.ts} +73 -46
- package/dist/chunks/continuous-sync-POEQXR25.ts.map +7 -0
- package/dist/chunks/{manager-ui-FXXO6TW4.ts → manager-ui-26LEINEX.ts} +2 -2
- package/dist/chunks/{manager-ui-FXXO6TW4.ts.map → manager-ui-26LEINEX.ts.map} +1 -1
- package/dist/chunks/{sync-inspection-5MY2HI4P.ts → sync-inspection-J25EEKZK.ts} +3 -3
- package/dist/chunks/{sync-operations-GNPS6BLY.ts → sync-operations-ZHA6HQDB.ts} +4 -4
- package/dist/index.ts +53 -18
- package/dist/index.ts.map +3 -3
- package/docs/continuous-sync-verification.md +10 -0
- package/package.json +2 -2
- package/skills/configure-pi-sync/references/configuration.md +8 -4
- package/src/sync/automatic-sync.ts +11 -6
- package/src/sync/continuous-sync.ts +78 -41
- package/src/sync/startup-check.ts +9 -3
- package/src/sync/startup-timings.ts +8 -4
- package/src/sync-extension.ts +18 -6
- package/src/ui/settings-ui.ts +1 -1
- package/src/ui/startup-timings-entry.ts +36 -0
- package/dist/chunks/chunk-UZPMDLTL.ts.map +0 -7
- package/dist/chunks/continuous-sync-U4HIKPQK.ts.map +0 -7
- /package/dist/chunks/{chunk-R75IHAOJ.ts.map → chunk-N5TFMPB5.ts.map} +0 -0
- /package/dist/chunks/{chunk-DT6TOCIG.ts.map → chunk-PQW6GS4J.ts.map} +0 -0
- /package/dist/chunks/{conflict-review-T7GSOKNG.ts.map → conflict-review-UC5AGVER.ts.map} +0 -0
- /package/dist/chunks/{sync-inspection-5MY2HI4P.ts.map → sync-inspection-J25EEKZK.ts.map} +0 -0
- /package/dist/chunks/{sync-operations-GNPS6BLY.ts.map → sync-operations-ZHA6HQDB.ts.map} +0 -0
package/README.md
CHANGED
|
@@ -167,7 +167,7 @@ Missing settings stay unconfigured without creating files or locks.
|
|
|
167
167
|
### Debug startup timings
|
|
168
168
|
|
|
169
169
|
Set the top-level `"debug": true` in `pi-sync.json`, or enable **Settings → Advanced → Debug startup timings**, then restart Pi or use `/reload`.
|
|
170
|
-
The default is `false`. Timing reports
|
|
170
|
+
The default is `false`. Timing reports remain in the TUI session transcript or arrive as RPC notifications, including the initial Continuous sync check. They do not enter model context or create a separate log file.
|
|
171
171
|
See [Debug startup timings](./skills/configure-pi-sync/references/configuration.md#debug-startup-timings) for measured stages and limits.
|
|
172
172
|
|
|
173
173
|
### Background startup checks
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
// src/sync/startup-timings.ts
|
|
5
5
|
import { performance } from "node:perf_hooks";
|
|
6
|
-
function createStartupTimings() {
|
|
6
|
+
function createStartupTimings(publishReport = (ctx, report) => ctx.ui.notify(report, "info")) {
|
|
7
7
|
const started = performance.now();
|
|
8
8
|
const stages = /* @__PURE__ */ new Map();
|
|
9
9
|
let unchanged = false;
|
|
@@ -30,7 +30,8 @@ function createStartupTimings() {
|
|
|
30
30
|
publish(ctx, enabled, sessionSignal, scope, outcome = "completed") {
|
|
31
31
|
if (!enabled || !ctx.hasUI || sessionSignal.aborted) return;
|
|
32
32
|
try {
|
|
33
|
-
|
|
33
|
+
publishReport(
|
|
34
|
+
ctx,
|
|
34
35
|
[
|
|
35
36
|
`pi-sync debug: ${scope} (${outcome})`,
|
|
36
37
|
...Array.from(
|
|
@@ -39,8 +40,7 @@ function createStartupTimings() {
|
|
|
39
40
|
),
|
|
40
41
|
...unchanged ? ["transfer result: unchanged (fast path)"] : [],
|
|
41
42
|
`total: ${(performance.now() - started).toFixed(1)} ms`
|
|
42
|
-
].join("\n")
|
|
43
|
-
"info"
|
|
43
|
+
].join("\n")
|
|
44
44
|
);
|
|
45
45
|
} catch {
|
|
46
46
|
}
|
|
@@ -51,4 +51,4 @@ function createStartupTimings() {
|
|
|
51
51
|
export {
|
|
52
52
|
createStartupTimings
|
|
53
53
|
};
|
|
54
|
-
//# sourceMappingURL=chunk-
|
|
54
|
+
//# sourceMappingURL=chunk-M6VQJIOU.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/sync/startup-timings.ts"],
|
|
4
|
+
"sourcesContent": ["import { performance } from \"node:perf_hooks\";\nimport type { ExtensionContext } from \"@earendil-works/pi-coding-agent\";\n\ntype StartupStage =\n | \"transaction recovery\"\n | \"settings read\"\n | \"config resolution\"\n | \"inspection import\"\n | \"inspection and guards\"\n | \"backend initialization\"\n | \"local snapshot\"\n | \"sync state read\"\n | \"remote head\"\n | \"operations import\"\n | \"automatic transfer\"\n | \"transfer authorization\"\n | \"transfer backend initialization\"\n | \"transfer journal read\"\n | \"transfer journal recovery\"\n | \"transfer state read\"\n | \"transfer local snapshot\"\n | \"transfer remote head\"\n | \"transfer snapshot download\"\n | \"transfer unchanged verification\"\n | \"transfer merge planning\"\n | \"transfer settings merge\"\n | \"transfer content merge\"\n | \"transfer preflight\"\n | \"transfer backup\"\n | \"transfer journal write\"\n | \"transfer remote publication\"\n | \"transfer local apply\"\n | \"transfer baseline write\"\n | \"transfer cleanup\";\n\nexport type StartupTimingPublisher = (ctx: ExtensionContext, report: string) => void;\n\n/** Fixed labels and durations only: never retain errors, paths, settings, or payloads. */\nexport function createStartupTimings(\n publishReport: StartupTimingPublisher = (ctx, report) => ctx.ui.notify(report, \"info\"),\n) {\n const started = performance.now();\n const stages = new Map<StartupStage, { ms: number; calls: number; interrupted: boolean }>();\n let unchanged = false;\n return {\n markUnchanged() {\n unchanged = true;\n },\n async measure<T>(stage: StartupStage, run: () => T | Promise<T>): Promise<T> {\n const start = performance.now();\n let completed = false;\n try {\n const result = await run();\n completed = true;\n return result;\n } finally {\n const previous = stages.get(stage);\n stages.set(stage, {\n ms: (previous?.ms ?? 0) + performance.now() - start,\n calls: (previous?.calls ?? 0) + 1,\n interrupted: Boolean(previous?.interrupted || !completed),\n });\n }\n },\n publish(\n ctx: ExtensionContext,\n enabled: boolean,\n sessionSignal: AbortSignal,\n scope: \"local initialization\" | \"background startup\" | \"continuous startup\",\n outcome: \"completed\" | \"stopped\" = \"completed\",\n ) {\n if (!enabled || !ctx.hasUI || sessionSignal.aborted) return;\n try {\n publishReport(\n ctx,\n [\n `pi-sync debug: ${scope} (${outcome})`,\n ...Array.from(\n stages,\n ([stage, value]) =>\n `${stage}: ${value.ms.toFixed(1)} ms${value.calls > 1 ? ` (${value.calls} calls)` : \"\"}${value.interrupted ? \" (interrupted)\" : \"\"}`,\n ),\n ...(unchanged ? [\"transfer result: unchanged (fast path)\"] : []),\n `total: ${(performance.now() - started).toFixed(1)} ms`,\n ].join(\"\\n\"),\n );\n } catch {\n // Diagnostics must not change sync behavior if the UI is unavailable during teardown.\n }\n },\n };\n}\n\nexport type StartupTimings = ReturnType<typeof createStartupTimings>;\n"],
|
|
5
|
+
"mappings": ";;;;AAAA,SAAS,mBAAmB;AAsCrB,SAAS,qBACd,gBAAwC,CAAC,KAAK,WAAW,IAAI,GAAG,OAAO,QAAQ,MAAM,GACrF;AACA,QAAM,UAAU,YAAY,IAAI;AAChC,QAAM,SAAS,oBAAI,IAAuE;AAC1F,MAAI,YAAY;AAChB,SAAO;AAAA,IACL,gBAAgB;AACd,kBAAY;AAAA,IACd;AAAA,IACA,MAAM,QAAW,OAAqB,KAAuC;AAC3E,YAAM,QAAQ,YAAY,IAAI;AAC9B,UAAI,YAAY;AAChB,UAAI;AACF,cAAM,SAAS,MAAM,IAAI;AACzB,oBAAY;AACZ,eAAO;AAAA,MACT,UAAE;AACA,cAAM,WAAW,OAAO,IAAI,KAAK;AACjC,eAAO,IAAI,OAAO;AAAA,UAChB,KAAK,UAAU,MAAM,KAAK,YAAY,IAAI,IAAI;AAAA,UAC9C,QAAQ,UAAU,SAAS,KAAK;AAAA,UAChC,aAAa,QAAQ,UAAU,eAAe,CAAC,SAAS;AAAA,QAC1D,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IACA,QACE,KACA,SACA,eACA,OACA,UAAmC,aACnC;AACA,UAAI,CAAC,WAAW,CAAC,IAAI,SAAS,cAAc,QAAS;AACrD,UAAI;AACF;AAAA,UACE;AAAA,UACA;AAAA,YACE,kBAAkB,KAAK,KAAK,OAAO;AAAA,YACnC,GAAG,MAAM;AAAA,cACP;AAAA,cACA,CAAC,CAAC,OAAO,KAAK,MACZ,GAAG,KAAK,KAAK,MAAM,GAAG,QAAQ,CAAC,CAAC,MAAM,MAAM,QAAQ,IAAI,KAAK,MAAM,KAAK,YAAY,EAAE,GAAG,MAAM,cAAc,mBAAmB,EAAE;AAAA,YACtI;AAAA,YACA,GAAI,YAAY,CAAC,wCAAwC,IAAI,CAAC;AAAA,YAC9D,WAAW,YAAY,IAAI,IAAI,SAAS,QAAQ,CAAC,CAAC;AAAA,UACpD,EAAE,KAAK,IAAI;AAAA,QACb;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
} from "./chunk-CRKTAPSL.ts";
|
|
39
39
|
import {
|
|
40
40
|
createStartupTimings
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-M6VQJIOU.ts";
|
|
42
42
|
import {
|
|
43
43
|
backupLocal,
|
|
44
44
|
captureMutationOwner,
|
|
@@ -1977,4 +1977,4 @@ export {
|
|
|
1977
1977
|
createSyncDecision,
|
|
1978
1978
|
mergeSync
|
|
1979
1979
|
};
|
|
1980
|
-
//# sourceMappingURL=chunk-
|
|
1980
|
+
//# sourceMappingURL=chunk-N5TFMPB5.ts.map
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from "./chunk-BDB4IDM3.ts";
|
|
11
11
|
import {
|
|
12
12
|
createStartupTimings
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-M6VQJIOU.ts";
|
|
14
14
|
import {
|
|
15
15
|
throwIfAborted
|
|
16
16
|
} from "./chunk-PWMWOJP4.ts";
|
|
@@ -59,4 +59,4 @@ async function inspectSync(config, options, signal, factory = createSyncBackend,
|
|
|
59
59
|
export {
|
|
60
60
|
inspectSync
|
|
61
61
|
};
|
|
62
|
-
//# sourceMappingURL=chunk-
|
|
62
|
+
//# sourceMappingURL=chunk-PQW6GS4J.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
|
mergeSync
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-N5TFMPB5.ts";
|
|
6
6
|
import "./chunk-YK52VDXG.ts";
|
|
7
7
|
import {
|
|
8
8
|
createSyncBackend
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
import "./chunk-GNH73BJ5.ts";
|
|
18
18
|
import "./chunk-BDB4IDM3.ts";
|
|
19
19
|
import "./chunk-CRKTAPSL.ts";
|
|
20
|
-
import "./chunk-
|
|
20
|
+
import "./chunk-M6VQJIOU.ts";
|
|
21
21
|
import {
|
|
22
22
|
captureMutationOwner
|
|
23
23
|
} from "./chunk-UOHR7LRO.ts";
|
|
@@ -180,4 +180,4 @@ async function showConflicts(ctx, options, factory = createSyncBackend) {
|
|
|
180
180
|
export {
|
|
181
181
|
showConflicts
|
|
182
182
|
};
|
|
183
|
-
//# sourceMappingURL=conflict-review-
|
|
183
|
+
//# sourceMappingURL=conflict-review-UC5AGVER.ts.map
|
|
@@ -19,6 +19,9 @@ import {
|
|
|
19
19
|
withAgentSyncLock
|
|
20
20
|
} from "./chunk-WD6FJHCK.ts";
|
|
21
21
|
import "./chunk-3ST7RSYN.ts";
|
|
22
|
+
import {
|
|
23
|
+
createStartupTimings
|
|
24
|
+
} from "./chunk-M6VQJIOU.ts";
|
|
22
25
|
import {
|
|
23
26
|
setSyncStatus
|
|
24
27
|
} from "./chunk-K3RIEL6J.ts";
|
|
@@ -124,15 +127,19 @@ var systemClock = {
|
|
|
124
127
|
var LOCAL_CHECK_MS = 5e3;
|
|
125
128
|
var POLL_MS = 6e4;
|
|
126
129
|
var DEBOUNCE_MS = 1e3;
|
|
127
|
-
function createContinuousSync(loaders, clock = systemClock) {
|
|
130
|
+
function createContinuousSync(loaders, clock = systemClock, publish) {
|
|
131
|
+
const startups = /* @__PURE__ */ new WeakMap();
|
|
128
132
|
const repairNotices = /* @__PURE__ */ new WeakSet();
|
|
129
133
|
let task;
|
|
130
134
|
return {
|
|
131
|
-
start(ctx, sessionSignal, explicitRetry = false) {
|
|
135
|
+
start(ctx, sessionSignal, explicitRetry = false, debug = false) {
|
|
132
136
|
if (!ctx.hasUI || ctx.mode !== "tui" && ctx.mode !== "rpc" || sessionSignal.aborted || task) return;
|
|
133
137
|
const controller = new AbortController();
|
|
134
138
|
const signal = AbortSignal.any([sessionSignal, controller.signal]);
|
|
135
139
|
const validateContext = captureMutationOwner(ctx);
|
|
140
|
+
const previousStartup = startups.get(ctx.sessionManager);
|
|
141
|
+
const startup = previousStartup?.signal === sessionSignal ? previousStartup : { signal: sessionSignal, debug, reported: false };
|
|
142
|
+
startups.set(ctx.sessionManager, startup);
|
|
136
143
|
const current = {
|
|
137
144
|
owner: ctx.sessionManager,
|
|
138
145
|
controller,
|
|
@@ -150,7 +157,7 @@ function createContinuousSync(loaders, clock = systemClock) {
|
|
|
150
157
|
let explicit = explicitRetry;
|
|
151
158
|
while (!signal.aborted) {
|
|
152
159
|
try {
|
|
153
|
-
await run(ctx, signal, explicit);
|
|
160
|
+
await run(ctx, signal, explicit, startup);
|
|
154
161
|
return;
|
|
155
162
|
} catch {
|
|
156
163
|
if (signal.aborted) return;
|
|
@@ -184,7 +191,7 @@ function createContinuousSync(loaders, clock = systemClock) {
|
|
|
184
191
|
await current.promise;
|
|
185
192
|
}
|
|
186
193
|
};
|
|
187
|
-
async function run(ctx, signal, explicitRetry) {
|
|
194
|
+
async function run(ctx, signal, explicitRetry, startup) {
|
|
188
195
|
const validateOwner = captureMutationOwner(ctx, signal);
|
|
189
196
|
try {
|
|
190
197
|
while (!signal.aborted) {
|
|
@@ -205,7 +212,7 @@ function createContinuousSync(loaders, clock = systemClock) {
|
|
|
205
212
|
validateOwner();
|
|
206
213
|
});
|
|
207
214
|
if (lease) {
|
|
208
|
-
await monitor(ctx, config, binding, lease, signal, explicitRetry);
|
|
215
|
+
await monitor(ctx, config, binding, lease, signal, explicitRetry, startup);
|
|
209
216
|
explicitRetry = false;
|
|
210
217
|
} else setSyncStatus(ctx, "sync waiting: another local owner");
|
|
211
218
|
} finally {
|
|
@@ -233,7 +240,7 @@ function createContinuousSync(loaders, clock = systemClock) {
|
|
|
233
240
|
}
|
|
234
241
|
}
|
|
235
242
|
}
|
|
236
|
-
async function monitor(ctx, initial, binding, lease, parent, explicitRetry) {
|
|
243
|
+
async function monitor(ctx, initial, binding, lease, parent, explicitRetry, startup) {
|
|
237
244
|
const signal = AbortSignal.any([parent, lease.signal]);
|
|
238
245
|
const validateOwner = captureMutationOwner(ctx, signal);
|
|
239
246
|
let config = initial;
|
|
@@ -293,6 +300,10 @@ function createContinuousSync(loaders, clock = systemClock) {
|
|
|
293
300
|
const hintDue = dirtyAt === void 0 ? Number.POSITIVE_INFINITY : dirtyAt + DEBOUNCE_MS;
|
|
294
301
|
const due = Math.max(record.error === "budget" ? 0 : record.next, Math.min(pollDue, hintDue));
|
|
295
302
|
if (now >= due) {
|
|
303
|
+
const timings = createStartupTimings(publish);
|
|
304
|
+
const report = !startup.reported && startup.debug;
|
|
305
|
+
startup.reported = true;
|
|
306
|
+
let outcome = "stopped";
|
|
296
307
|
const force = explicitRetry || controlChanged;
|
|
297
308
|
explicitRetry = false;
|
|
298
309
|
const expectedModel = hashContinuous(ctx.model);
|
|
@@ -336,8 +347,10 @@ function createContinuousSync(loaders, clock = systemClock) {
|
|
|
336
347
|
AbortSignal.any([signal, cycle.signal]),
|
|
337
348
|
validateCycle,
|
|
338
349
|
configuration,
|
|
339
|
-
force
|
|
350
|
+
force,
|
|
351
|
+
timings
|
|
340
352
|
);
|
|
353
|
+
outcome = "completed";
|
|
341
354
|
} catch (error) {
|
|
342
355
|
if (signal.aborted || !ctx.isIdle()) return;
|
|
343
356
|
if (cycle.signal.aborted && cycle.signal.reason?.name !== "TimeoutError") {
|
|
@@ -372,6 +385,7 @@ function createContinuousSync(loaders, clock = systemClock) {
|
|
|
372
385
|
guard.abort();
|
|
373
386
|
await guardTask;
|
|
374
387
|
cycle = void 0;
|
|
388
|
+
timings.publish(ctx, report, signal, "continuous startup", outcome);
|
|
375
389
|
}
|
|
376
390
|
pollDue = clock.now() + POLL_MS + Math.floor(clock.random() * 6e3);
|
|
377
391
|
closeWatch();
|
|
@@ -402,7 +416,7 @@ function createContinuousSync(loaders, clock = systemClock) {
|
|
|
402
416
|
cycle?.abort();
|
|
403
417
|
}
|
|
404
418
|
}
|
|
405
|
-
async function performCycle(ctx, config, binding, lease, signal, validateOwner, configuration, force) {
|
|
419
|
+
async function performCycle(ctx, config, binding, lease, signal, validateOwner, configuration, force, timings) {
|
|
406
420
|
const validate = (latest) => {
|
|
407
421
|
signal.throwIfAborted();
|
|
408
422
|
validateOwner(latest);
|
|
@@ -415,27 +429,36 @@ function createContinuousSync(loaders, clock = systemClock) {
|
|
|
415
429
|
if (!force && !pending && current.phase === "blocked" && ["authentication", "storage", "unknown"].includes(current.error ?? ""))
|
|
416
430
|
return;
|
|
417
431
|
setSyncStatus(ctx, "sync checking");
|
|
418
|
-
const inspectionModule = await loaders.inspection();
|
|
432
|
+
const inspectionModule = await timings.measure("inspection import", () => loaders.inspection());
|
|
419
433
|
validate();
|
|
420
|
-
const observed = await
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
validate();
|
|
424
|
-
let localIdentity = inspection.localIdentity;
|
|
425
|
-
if (!localIdentity) {
|
|
426
|
-
const snapshotModule = await loaders.snapshot();
|
|
434
|
+
const observed = await timings.measure(
|
|
435
|
+
"inspection and guards",
|
|
436
|
+
() => guardedLock("continuous-check", async () => {
|
|
427
437
|
validate();
|
|
428
|
-
const
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
438
|
+
const inspection = await inspectionModule.inspectSync(
|
|
439
|
+
config,
|
|
440
|
+
snapshotOptionsForContext(ctx, config),
|
|
441
|
+
signal,
|
|
442
|
+
void 0,
|
|
443
|
+
timings
|
|
444
|
+
);
|
|
432
445
|
validate();
|
|
433
|
-
localIdentity =
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
446
|
+
let localIdentity = inspection.localIdentity;
|
|
447
|
+
if (!localIdentity) {
|
|
448
|
+
const snapshotModule = await loaders.snapshot();
|
|
449
|
+
validate();
|
|
450
|
+
const local = await snapshotModule.createSnapshot(config.snapshotIdentity, {
|
|
451
|
+
...snapshotOptionsForContext(ctx, config),
|
|
452
|
+
signal
|
|
453
|
+
});
|
|
454
|
+
validate();
|
|
455
|
+
localIdentity = hashContinuous(fileHashMap(local));
|
|
456
|
+
}
|
|
457
|
+
const journal = await readMergeJournal(config);
|
|
458
|
+
validate();
|
|
459
|
+
return { inspection, journal, localIdentity };
|
|
460
|
+
})
|
|
461
|
+
);
|
|
439
462
|
validate();
|
|
440
463
|
const evidence = hashContinuous([
|
|
441
464
|
configuration,
|
|
@@ -465,27 +488,31 @@ function createContinuousSync(loaders, clock = systemClock) {
|
|
|
465
488
|
throw new ContinuousError("unsafe", "Continuous sync needs an accepted baseline and matching remote selection.");
|
|
466
489
|
let transferred = false;
|
|
467
490
|
if (observed.journal || observed.inspection.localChanged || observed.inspection.remoteChanged) {
|
|
468
|
-
const operations = await loaders.operations();
|
|
491
|
+
const operations = await timings.measure("operations import", () => loaders.operations());
|
|
469
492
|
validate();
|
|
470
493
|
setSyncStatus(ctx, "sync syncing");
|
|
471
|
-
const result = await
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
494
|
+
const result = await timings.measure(
|
|
495
|
+
"automatic transfer",
|
|
496
|
+
() => withStateDirectoryAccess(
|
|
497
|
+
() => withAgentSyncLock(
|
|
498
|
+
ctx,
|
|
499
|
+
{
|
|
500
|
+
args: [],
|
|
501
|
+
yes: true,
|
|
502
|
+
force: false,
|
|
503
|
+
stale: false,
|
|
504
|
+
silent: true,
|
|
505
|
+
reload: false,
|
|
506
|
+
auto: true,
|
|
507
|
+
signal,
|
|
508
|
+
startupTimings: timings,
|
|
509
|
+
background: {
|
|
510
|
+
validate,
|
|
511
|
+
reserve: (key, requestSignal) => reserveContinuousRequest(binding, lease, key, () => clock.now(), requestSignal)
|
|
512
|
+
}
|
|
513
|
+
},
|
|
514
|
+
(options) => operations.syncBoth(ctx, options)
|
|
515
|
+
)
|
|
489
516
|
)
|
|
490
517
|
);
|
|
491
518
|
validate();
|
|
@@ -542,4 +569,4 @@ export {
|
|
|
542
569
|
continuousEnabled,
|
|
543
570
|
createContinuousSync
|
|
544
571
|
};
|
|
545
|
-
//# sourceMappingURL=continuous-sync-
|
|
572
|
+
//# sourceMappingURL=continuous-sync-POEQXR25.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 } 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 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\");\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 }\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 );\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\");\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\");\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
|
+
}
|
|
@@ -1485,7 +1485,7 @@ async function showSyncSettings(ctx, runRoute, signal) {
|
|
|
1485
1485
|
{
|
|
1486
1486
|
id: "debug",
|
|
1487
1487
|
label: "Debug startup timings",
|
|
1488
|
-
description: "All setups on this device: show startup durations in TUI
|
|
1488
|
+
description: "All setups on this device: show startup durations in the TUI transcript or RPC notifications, including initial Continuous sync. Applies next session start; no credentials or file contents.",
|
|
1489
1489
|
currentValue: state.debug ? "On" : "Off",
|
|
1490
1490
|
values: ["On", "Off"],
|
|
1491
1491
|
action: "debug"
|
|
@@ -2131,4 +2131,4 @@ function syncMainMenuItem(label) {
|
|
|
2131
2131
|
export {
|
|
2132
2132
|
showSyncManager
|
|
2133
2133
|
};
|
|
2134
|
-
//# sourceMappingURL=manager-ui-
|
|
2134
|
+
//# sourceMappingURL=manager-ui-26LEINEX.ts.map
|