@narumitw/pi-sync 0.57.11 → 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.
- package/CHANGELOG.md +14 -0
- package/README.md +29 -21
- package/dist/chunks/{agent-candidate-OCDPRI5G.ts → agent-candidate-U2NU3GUX.ts} +2 -2
- package/dist/chunks/{agent-plan-P5B5RGZ7.ts → agent-plan-3YXDIJXO.ts} +13 -10
- package/dist/chunks/agent-plan-3YXDIJXO.ts.map +7 -0
- package/dist/chunks/{agent-runner-WMSCKSCB.ts → agent-runner-FCRV2Z75.ts} +11 -10
- package/dist/chunks/agent-runner-FCRV2Z75.ts.map +7 -0
- package/dist/chunks/{agent-store-RJSMNOYP.ts → agent-store-7GINKTS7.ts} +2 -2
- package/dist/chunks/{agent-store-RJSMNOYP.ts.map → agent-store-7GINKTS7.ts.map} +2 -2
- package/dist/chunks/{agent-sync-EUK2CPSS.ts → agent-sync-2R4GG2MF.ts} +3 -3
- package/dist/chunks/{chunk-67INJPKR.ts → chunk-CQD2TJHE.ts} +4 -4
- package/dist/chunks/{chunk-67INJPKR.ts.map → chunk-CQD2TJHE.ts.map} +2 -2
- package/dist/chunks/{chunk-ZDDBZH72.ts → chunk-JYILGR3K.ts} +2 -2
- package/dist/chunks/{chunk-OKPPZA4D.ts → chunk-MG66XM5U.ts} +3 -3
- package/dist/chunks/{chunk-OKPPZA4D.ts.map → chunk-MG66XM5U.ts.map} +2 -2
- package/dist/chunks/{chunk-7OLLPPLU.ts → chunk-MMQIEDZ6.ts} +6 -6
- package/dist/chunks/{chunk-7OLLPPLU.ts.map → chunk-MMQIEDZ6.ts.map} +2 -2
- package/dist/chunks/{chunk-Q23JJW7E.ts → chunk-MW6KUQYA.ts} +7 -5
- package/dist/chunks/chunk-MW6KUQYA.ts.map +7 -0
- package/dist/chunks/{chunk-NLWS55B6.ts → chunk-QPC5HT3A.ts} +2 -2
- package/dist/chunks/{chunk-NLWS55B6.ts.map → chunk-QPC5HT3A.ts.map} +1 -1
- package/dist/chunks/{chunk-DRTC4PKM.ts → chunk-S5OCYVPS.ts} +2 -2
- package/dist/chunks/{chunk-DRTC4PKM.ts.map → chunk-S5OCYVPS.ts.map} +2 -2
- package/dist/chunks/{chunk-3IYAPMST.ts → chunk-U6GXGY5G.ts} +2 -2
- package/dist/chunks/{chunk-F7E3VFXU.ts → chunk-WQMYV4DW.ts} +8 -8
- package/dist/chunks/chunk-WQMYV4DW.ts.map +7 -0
- package/dist/chunks/{chunk-CPT2BN6N.ts → chunk-XEODG2PE.ts} +2 -2
- package/dist/chunks/chunk-YIPK23JW.ts +171 -0
- package/dist/chunks/chunk-YIPK23JW.ts.map +7 -0
- package/dist/chunks/{command-handler-F2E7A5T5.ts → command-handler-KCB6MCWS.ts} +12 -12
- package/dist/chunks/{command-handler-F2E7A5T5.ts.map → command-handler-KCB6MCWS.ts.map} +2 -2
- package/dist/chunks/{conflict-review-2QMO2K6Q.ts → conflict-review-GXA6Y7KY.ts} +2 -2
- package/dist/chunks/{continuous-record-AH7JGYKM.ts → continuous-record-EPHGR2DU.ts} +2 -2
- package/dist/chunks/{continuous-sync-VRMXCA5X.ts → continuous-sync-FAFNLEUW.ts} +19 -11
- package/dist/chunks/continuous-sync-FAFNLEUW.ts.map +7 -0
- package/dist/chunks/{manager-result-dispatcher-6W52NM7F.ts → manager-result-dispatcher-XCYPW7RC.ts} +4 -4
- package/dist/chunks/{manager-ui-LM7DSJ2Y.ts → manager-ui-FMZXKPX2.ts} +153 -183
- package/dist/chunks/manager-ui-FMZXKPX2.ts.map +7 -0
- package/dist/chunks/{remote-selection-ui-TD4C4W3J.ts → remote-selection-ui-MYM2YCPF.ts} +3 -3
- package/dist/chunks/{setup-switch-PIPXYPCW.ts → setup-switch-KLGESLQX.ts} +3 -3
- package/dist/chunks/{setup-wizard-RR5U3SUB.ts → setup-wizard-ZQAK35BP.ts} +3 -3
- package/dist/chunks/{sync-operations-CV3TULLD.ts → sync-operations-45APGOL3.ts} +9 -9
- package/dist/chunks/sync-operations-45APGOL3.ts.map +7 -0
- package/dist/index.ts +80 -65
- package/dist/index.ts.map +2 -2
- package/docs/agent-continuous-hardening.md +5 -5
- package/docs/agent-mode-verification.md +3 -3
- package/docs/agent-quality-verification.md +3 -3
- package/docs/continuous-sync-verification.md +2 -2
- package/docs/settings.md +9 -5
- package/docs/tui-contract.md +57 -3
- package/package.json +3 -3
- package/skills/configure-pi-sync/SKILL.md +3 -1
- package/skills/configure-pi-sync/references/configuration.md +61 -38
- package/src/commands/command-execution.ts +3 -3
- package/src/commands/command.ts +1 -1
- package/src/settings/settings-types.ts +1 -1
- package/src/sync/agent-candidate.ts +3 -3
- package/src/sync/agent-plan.ts +11 -8
- package/src/sync/agent-runner.ts +10 -9
- package/src/sync/agent-store.ts +1 -1
- package/src/sync/agent-sync.ts +3 -3
- package/src/sync/continuous-record.ts +1 -1
- package/src/sync/continuous-sync.ts +15 -6
- package/src/sync/merged-sync.ts +4 -4
- package/src/sync/startup-check.ts +1 -1
- package/src/sync/sync-mutations.ts +3 -3
- package/src/sync/sync-queries.ts +2 -2
- package/src/sync-extension.ts +71 -57
- package/src/ui/agent-mode-setting.ts +6 -6
- package/src/ui/manager-state.ts +1 -1
- package/src/ui/remote-selection-ui.ts +1 -1
- package/src/ui/settings-ui.ts +19 -55
- package/src/ui/setup/setup-switcher.ts +2 -2
- package/src/ui/sync-attention.ts +5 -3
- package/src/ui/sync-setups-ui.ts +2 -2
- package/src/ui/sync-status.ts +214 -3
- package/dist/chunks/agent-plan-P5B5RGZ7.ts.map +0 -7
- package/dist/chunks/agent-runner-WMSCKSCB.ts.map +0 -7
- package/dist/chunks/chunk-F7E3VFXU.ts.map +0 -7
- package/dist/chunks/chunk-K3RIEL6J.ts +0 -20
- package/dist/chunks/chunk-K3RIEL6J.ts.map +0 -7
- package/dist/chunks/chunk-Q23JJW7E.ts.map +0 -7
- package/dist/chunks/continuous-sync-VRMXCA5X.ts.map +0 -7
- package/dist/chunks/manager-ui-LM7DSJ2Y.ts.map +0 -7
- package/dist/chunks/sync-operations-CV3TULLD.ts.map +0 -7
- /package/dist/chunks/{agent-candidate-OCDPRI5G.ts.map → agent-candidate-U2NU3GUX.ts.map} +0 -0
- /package/dist/chunks/{agent-sync-EUK2CPSS.ts.map → agent-sync-2R4GG2MF.ts.map} +0 -0
- /package/dist/chunks/{chunk-ZDDBZH72.ts.map → chunk-JYILGR3K.ts.map} +0 -0
- /package/dist/chunks/{chunk-3IYAPMST.ts.map → chunk-U6GXGY5G.ts.map} +0 -0
- /package/dist/chunks/{chunk-CPT2BN6N.ts.map → chunk-XEODG2PE.ts.map} +0 -0
- /package/dist/chunks/{conflict-review-2QMO2K6Q.ts.map → conflict-review-GXA6Y7KY.ts.map} +0 -0
- /package/dist/chunks/{continuous-record-AH7JGYKM.ts.map → continuous-record-EPHGR2DU.ts.map} +0 -0
- /package/dist/chunks/{manager-result-dispatcher-6W52NM7F.ts.map → manager-result-dispatcher-XCYPW7RC.ts.map} +0 -0
- /package/dist/chunks/{remote-selection-ui-TD4C4W3J.ts.map → remote-selection-ui-MYM2YCPF.ts.map} +0 -0
- /package/dist/chunks/{setup-switch-PIPXYPCW.ts.map → setup-switch-KLGESLQX.ts.map} +0 -0
- /package/dist/chunks/{setup-wizard-RR5U3SUB.ts.map → setup-wizard-ZQAK35BP.ts.map} +0 -0
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from "./chunk-AMJRUXFT.ts";
|
|
6
6
|
import {
|
|
7
7
|
setSyncStatus
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-YIPK23JW.ts";
|
|
9
9
|
import {
|
|
10
10
|
syncCheckConfigFingerprint,
|
|
11
11
|
syncConfigReviewFingerprint
|
|
@@ -75,7 +75,9 @@ function createSyncAttentionController() {
|
|
|
75
75
|
}
|
|
76
76
|
if (!state && classification === "status") {
|
|
77
77
|
ctx.ui.setWidget(WIDGET_KEY, void 0);
|
|
78
|
-
setSyncStatus(ctx, observation?.inspection.remoteChanged ? "sync \u21E3" : "sync \u21E1"
|
|
78
|
+
setSyncStatus(ctx, observation?.inspection.remoteChanged ? "sync \u21E3" : "sync \u21E1", {
|
|
79
|
+
activity: observation?.inspection.remoteChanged ? "remote-change" : "local-change"
|
|
80
|
+
});
|
|
79
81
|
return;
|
|
80
82
|
}
|
|
81
83
|
const presentation = state ? attentionPresentation(state.decision) : {
|
|
@@ -84,7 +86,7 @@ function createSyncAttentionController() {
|
|
|
84
86
|
};
|
|
85
87
|
if (ctx.mode !== "tui") {
|
|
86
88
|
ctx.ui.setWidget(WIDGET_KEY, void 0);
|
|
87
|
-
setSyncStatus(ctx, presentation.status);
|
|
89
|
+
setSyncStatus(ctx, presentation.status, { activity: "review" });
|
|
88
90
|
return;
|
|
89
91
|
}
|
|
90
92
|
const { EditorStatusWidget } = await import("./attention-widget-Z7G3SYYJ.ts").catch((error) => {
|
|
@@ -92,7 +94,7 @@ function createSyncAttentionController() {
|
|
|
92
94
|
throw error;
|
|
93
95
|
});
|
|
94
96
|
if (generation !== currentGeneration || signal?.aborted) return;
|
|
95
|
-
setSyncStatus(ctx, presentation.status);
|
|
97
|
+
setSyncStatus(ctx, presentation.status, { activity: "review" });
|
|
96
98
|
ctx.ui.setWidget(
|
|
97
99
|
WIDGET_KEY,
|
|
98
100
|
(_tui, theme) => new EditorStatusWidget({
|
|
@@ -164,4 +166,4 @@ export {
|
|
|
164
166
|
observationMatchesConfig,
|
|
165
167
|
observationSummary
|
|
166
168
|
};
|
|
167
|
-
//# sourceMappingURL=chunk-
|
|
169
|
+
//# sourceMappingURL=chunk-MW6KUQYA.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/ui/sync-attention.ts"],
|
|
4
|
+
"sourcesContent": ["import type { ExtensionContext } from \"@earendil-works/pi-coding-agent\";\nimport { truncateToWidth } from \"@earendil-works/pi-tui\";\nimport { syncCheckConfigFingerprint, syncConfigReviewFingerprint } from \"../settings/config.js\";\nimport type { AnySyncConfig } from \"../settings/settings-types.js\";\nimport type { StartupObservation } from \"../sync/sync-inspection.js\";\nimport { compareSyncInclude, type RemoteSelectionDecision, sameSyncInclude } from \"../sync/sync-policy.js\";\nimport { setSyncStatus } from \"./sync-status.js\";\nimport { safeTerminalText } from \"./terminal-text.js\";\n\nconst WIDGET_KEY = \"sync:attention\";\n\nexport type SyncAttentionOrigin = \"sync\" | \"pull\" | \"push\";\n\nexport interface SyncAttentionState {\n decision: RemoteSelectionDecision;\n origin: SyncAttentionOrigin;\n offered: boolean;\n}\n\nexport function syncAttentionMatchesConfig(attention: SyncAttentionState, config: AnySyncConfig) {\n return (\n attention.decision.setupName === config.setupName &&\n attention.decision.configIdentity === syncConfigReviewFingerprint(config) &&\n sameSyncInclude(attention.decision.localInclude, config.include)\n );\n}\n\nexport interface SyncAttentionController {\n observe(observation: StartupObservation): void;\n observation(): StartupObservation | undefined;\n clearObservation(): void;\n notifyObservation(ctx: ExtensionContext): void;\n set(decision: RemoteSelectionDecision, origin: SyncAttentionOrigin): void;\n current(): SyncAttentionState | undefined;\n markOffered(): boolean;\n clear(ctx: ExtensionContext): void;\n reset(ctx: ExtensionContext): void;\n publish(ctx: ExtensionContext, signal?: AbortSignal): Promise<void>;\n}\n\nexport function createSyncAttentionController(): SyncAttentionController {\n let state: SyncAttentionState | undefined;\n let observation: StartupObservation | undefined;\n let generation = 0;\n\n return {\n observe(value) {\n generation++;\n observation = value;\n },\n observation() {\n return observation;\n },\n clearObservation() {\n generation++;\n observation = undefined;\n },\n notifyObservation(ctx) {\n if (ctx.hasUI && observation && observationNeedsAttention(observation)) {\n ctx.ui.notify(observationLines(observation).join(\"\\n\"), \"warning\");\n }\n },\n set(decision, origin) {\n generation++;\n state = { decision, origin, offered: false };\n },\n current() {\n return state;\n },\n markOffered() {\n if (!state || state.offered) return false;\n state = { ...state, offered: true };\n return true;\n },\n clear(ctx) {\n generation++;\n state = undefined;\n clearAttentionPresentation(ctx);\n },\n reset(ctx) {\n generation++;\n state = undefined;\n observation = undefined;\n clearAttentionPresentation(ctx);\n },\n async publish(ctx, signal) {\n const currentGeneration = ++generation;\n if (signal?.aborted || !ctx.hasUI) return;\n const classification = observation ? classifyObservation(observation) : \"none\";\n if (!state && (classification === \"none\" || classification === \"guidance\")) {\n clearAttentionPresentation(ctx);\n return;\n }\n if (!state && classification === \"status\") {\n ctx.ui.setWidget(WIDGET_KEY, undefined);\n setSyncStatus(ctx, observation?.inspection.remoteChanged ? \"sync \u21E3\" : \"sync \u21E1\", {\n activity: observation?.inspection.remoteChanged ? \"remote-change\" : \"local-change\",\n });\n return;\n }\n const presentation = state\n ? attentionPresentation(state.decision)\n : {\n status: \"sync \u21D5\",\n lines: observationLines(observation as StartupObservation),\n };\n if (ctx.mode !== \"tui\") {\n ctx.ui.setWidget(WIDGET_KEY, undefined);\n setSyncStatus(ctx, presentation.status, { activity: \"review\" });\n return;\n }\n // Keep Kit outside the eager startup graph; module loading owns no cancellable resources.\n const { EditorStatusWidget } = await import(\"./attention-widget.js\").catch((error) => {\n if (generation === currentGeneration && !signal?.aborted) clearAttentionPresentation(ctx);\n throw error;\n });\n if (generation !== currentGeneration || signal?.aborted) return;\n setSyncStatus(ctx, presentation.status, { activity: \"review\" });\n ctx.ui.setWidget(\n WIDGET_KEY,\n (_tui, theme) =>\n new EditorStatusWidget({\n theme,\n renderBody: (width) =>\n presentation.lines.map((line, index) =>\n width === 0 ? \"\" : truncateToWidth(theme.fg(index === 0 ? \"warning\" : \"muted\", line), width, \"\u2026\"),\n ),\n }),\n );\n },\n };\n}\n\nfunction attentionPresentation(decision: RemoteSelectionDecision) {\n const setupName = safeTerminalText(decision.setupName);\n const comparison = compareSyncInclude(decision.localInclude, decision.remoteInclude);\n const difference =\n comparison.remoteOnly.length === 0 && comparison.localOnly.length === 0\n ? \"Only list order differs\"\n : `Remote ${comparison.remoteOnly.length} \u00B7 Device ${comparison.localOnly.length}`;\n return {\n status: \"sync \u21D5\",\n lines: [`Pi Sync needs review \u00B7 ${setupName}`, difference, \"No changes \u00B7 Run /sync to review\"],\n };\n}\n\nexport function observationMatchesConfig(observation: StartupObservation, config: AnySyncConfig) {\n return observation.configIdentity === syncCheckConfigFingerprint(config);\n}\n\nexport function observationSummary(observation: StartupObservation) {\n const result = observation.inspection;\n if (result.emptyInclude) return \"No included content selected\";\n if (result.selectionState?.kind === \"different\") return \"Synced-content list differs; review needed\";\n if (result.firstSync)\n return result.head ? \"No sync baseline; review remote and local content\" : \"Remote empty; no sync baseline\";\n if (!result.head) return \"Remote snapshot missing; review needed\";\n if (observation.automaticTransfer && result.selectionState?.kind === \"legacy\")\n return \"Legacy remote has no authoritative content list; review /sync and choose an explicit direction to adopt policy\";\n if (result.localChanged && result.remoteChanged) return \"Local and remote changed since last sync; review needed\";\n if (result.remoteChanged) return \"Remote changed since last sync\";\n if (result.localChanged) return \"Local content changed since last sync\";\n if (result.selectionState?.kind === \"legacy\") return \"Legacy remote has no authoritative content list\";\n return \"No changes detected since last sync\";\n}\n\nexport type ObservationClassification = \"none\" | \"guidance\" | \"status\" | \"review\";\n\n/** Presentation only: never discard an observation or authorize a transfer here. */\nexport function classifyObservation(observation: StartupObservation): ObservationClassification {\n const result = observation.inspection;\n // Sync now exits before reading remote content when nothing is selected.\n if (result.emptyInclude) return \"guidance\";\n // Ordering is part of the existing transfer policy, not merely display order.\n if (result.selectionState?.kind === \"different\") return \"review\";\n if (result.firstSync) return result.head ? \"review\" : \"guidance\";\n if (!result.head || (result.localChanged && result.remoteChanged)) return \"review\";\n if (observation.automaticTransfer && result.selectionState?.kind === \"legacy\") return \"review\";\n if (result.localChanged || result.remoteChanged) return \"status\";\n // Legacy metadata alone requires no scope confirmation in transfer operations.\n return \"none\";\n}\n\nexport function observationNeedsAttention(observation: StartupObservation) {\n return classifyObservation(observation) === \"review\";\n}\n\nfunction observationLines(observation: StartupObservation) {\n return [\n `Pi Sync check \u00B7 ${safeTerminalText(observation.setupName)}`,\n observationSummary(observation),\n \"No startup transfer \u00B7 Run /sync to review\",\n ];\n}\n\nfunction clearAttentionPresentation(ctx: ExtensionContext) {\n if (!ctx.hasUI) return;\n setSyncStatus(ctx, undefined);\n ctx.ui.setWidget(WIDGET_KEY, undefined);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -220,7 +220,7 @@ function usage() {
|
|
|
220
220
|
`Automatic sync: ${AUTOMATIC_SYNC_DESCRIPTION}`,
|
|
221
221
|
`Startup transfer: ${STARTUP_TRANSFER_DESCRIPTION}`,
|
|
222
222
|
"Automatic transfer at startup is a separate opt-in: one conflict-free established-baseline transfer at idle in TUI/RPC, with conditional/lease publication and no resource reload.",
|
|
223
|
-
"
|
|
223
|
+
"Continuous sync is a separate default-Off opt-in in Settings. It requires Autonomous sync, monitors while Pi is open, and can incur recurring network/model costs. Safety blocks and durable automatic request limits remain.",
|
|
224
224
|
"Settings: use /sync init or edit storage connections and sync setups in ~/.pi/agent/pi-sync.json (or the configured Pi agent directory). Version 1 and version 2 settings are unsupported and are never rewritten."
|
|
225
225
|
].join("\n");
|
|
226
226
|
}
|
|
@@ -237,4 +237,4 @@ export {
|
|
|
237
237
|
resolveSyncCommand,
|
|
238
238
|
usage
|
|
239
239
|
};
|
|
240
|
-
//# sourceMappingURL=chunk-
|
|
240
|
+
//# sourceMappingURL=chunk-QPC5HT3A.ts.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/ui/sync-behavior.ts", "../../src/commands/command.ts"],
|
|
4
|
-
"sourcesContent": ["export const AUTOMATIC_SYNC_DESCRIPTION =\n \"This setup: check remote state once at startup in TUI/RPC. At shutdown, push all selected content only when sessions are included; reload skips that push. Saves apply to subsequent operations; a new check waits for the next session start. This does not enable startup transfer.\";\n\nexport const STARTUP_TRANSFER_DESCRIPTION =\n \"This setup: separate opt-in for one idle startup transfer in TUI/RPC. Requires an accepted baseline, matching remote included paths, and conditional or lease-protected publication (Git, verified WebDAV, or R2/S3 with verified conditional writes). May upload, replace, or remove selected files. Never reloads resources. Enabling applies next session start; opening Settings cancels pending work. Completed transfers are not undone.\";\n\nexport function startupTransferSummary(config: {\n automaticTransfer?: boolean;\n backend: { type: \"s3\" | \"git\" | \"webdav\" };\n}) {\n if (!config.automaticTransfer) return \"Off\";\n return config.backend.type === \"s3\"\n ? \"On (next idle startup; R2/S3 conditional-write verification required)\"\n : \"On (next idle startup; baseline and remote policy checks required)\";\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { AUTOMATIC_SYNC_DESCRIPTION, STARTUP_TRANSFER_DESCRIPTION } from \"../ui/sync-behavior.js\";\nimport type { CommandArgumentCompletion, CommandOptions } from \"./command-types.js\";\n\nconst YES_FLAG_COMPLETIONS: readonly CommandArgumentCompletion[] = [\n { value: \"--yes\", label: \"--yes\", description: \"Skip confirmation prompts\" },\n { value: \"-y\", label: \"-y\", description: \"Skip confirmation prompts\" },\n];\nexport const SYNC_COMMANDS = [\n { name: \"help\", description: \"Show command usage\" },\n { name: \"use\", description: \"Switch the current sync setup\", usageSuffix: \" <setup>\" },\n { name: \"init\", description: \"Create local config template\" },\n { name: \"config\", description: \"Show resolved configuration\" },\n { name: \"files\", description: \"Choose included content\" },\n { name: \"status\", description: \"Show sync status\" },\n { name: \"diff\", description: \"Show local/remote diff\" },\n { name: \"conflicts\", description: \"Review private unresolved conflict groups\" },\n { name: \"doctor\", description: \"Check config, secrets, and lock state\" },\n { name: \"push\", description: \"Upload local settings\" },\n { name: \"pull\", description: \"Apply remote settings\" },\n { name: \"sync\", description: \"Push or pull as needed\" },\n { name: \"history\", description: \"Show recent remote snapshots\" },\n { name: \"rollback\", description: \"Apply a previous snapshot\", usageSuffix: \" <snapshot>\" },\n { name: \"migrate-state\", description: \"Move legacy state into pi-sync/\" },\n { name: \"unlock\", description: \"Remove a stale local lock\", usageSuffix: \" --stale\" },\n] as const;\n\nexport type SyncCommandName = (typeof SYNC_COMMANDS)[number][\"name\"];\n\nconst SYNC_COMMAND_COMPLETIONS: readonly CommandArgumentCompletion[] = SYNC_COMMANDS.map(({ name, description }) => ({\n value: name,\n label: name,\n description,\n}));\nlet setupCompletionNames: string[] = [];\n\nexport function setSyncSetupCompletions(names: readonly string[]) {\n setupCompletionNames = [...new Set(names)].sort((left, right) => left.localeCompare(right));\n}\nconst SETUP_FLAG_COMPLETION = {\n value: \"--setup\",\n label: \"--setup\",\n description: \"Address a sync setup without switching\",\n} as const;\nconst SYNC_FLAG_COMPLETIONS: Record<string, readonly CommandArgumentCompletion[]> = {\n config: [SETUP_FLAG_COMPLETION],\n files: [SETUP_FLAG_COMPLETION],\n status: [SETUP_FLAG_COMPLETION],\n diff: [SETUP_FLAG_COMPLETION],\n conflicts: [SETUP_FLAG_COMPLETION],\n doctor: [SETUP_FLAG_COMPLETION],\n push: [\n ...YES_FLAG_COMPLETIONS,\n { value: \"--force\", label: \"--force\", description: \"Overwrite visible remote changes\" },\n SETUP_FLAG_COMPLETION,\n ],\n pull: [\n ...YES_FLAG_COMPLETIONS,\n { value: \"--force\", label: \"--force\", description: \"Overwrite local changes\" },\n SETUP_FLAG_COMPLETION,\n ],\n sync: [\n ...YES_FLAG_COMPLETIONS,\n { value: \"--force\", label: \"--force\", description: \"Resolve conflicts by forcing action\" },\n SETUP_FLAG_COMPLETION,\n ],\n history: [SETUP_FLAG_COMPLETION],\n rollback: [...YES_FLAG_COMPLETIONS, SETUP_FLAG_COMPLETION],\n \"migrate-state\": YES_FLAG_COMPLETIONS,\n unlock: [{ value: \"--stale\", label: \"--stale\", description: \"Remove only a stale lock\" }],\n};\n\nexport function splitArgs(input: string) {\n return input.match(/(?:[^\\s\"']+|\"[^\"]*\"|'[^']*')+/g)?.map((arg) => arg.replace(/^['\"]|['\"]$/g, \"\")) ?? [];\n}\n\nexport function parseOptions(args: string[]): CommandOptions {\n const values: string[] = [];\n let yes = false;\n let force = false;\n let stale = false;\n let setup: string | undefined;\n for (let index = 0; index < args.length; index += 1) {\n const arg = args[index];\n if (arg === \"--yes\" || arg === \"-y\") yes = true;\n else if (arg === \"--force\") force = true;\n else if (arg === \"--stale\") stale = true;\n else if (arg === \"--setup\") {\n const name = args[index + 1];\n if (!name || name.startsWith(\"-\")) throw new Error(\"--setup requires a sync setup name.\");\n if (setup !== undefined) throw new Error(\"--setup may be provided only once.\");\n setup = name;\n index += 1;\n } else if (arg.startsWith(\"-\")) {\n throw new Error(`Unknown sync option: ${arg}`);\n } else values.push(arg);\n }\n return {\n yes,\n force,\n stale,\n silent: false,\n reload: true,\n auto: false,\n ...(setup === undefined ? {} : { setup }),\n args: values,\n };\n}\n\nexport function validateCommandOptions(command: string, options: CommandOptions) {\n const setupAllowed = new Set([\n \"config\",\n \"files\",\n \"status\",\n \"diff\",\n \"conflicts\",\n \"doctor\",\n \"push\",\n \"pull\",\n \"sync\",\n \"history\",\n \"rollback\",\n ]);\n if (options.setup && !setupAllowed.has(command)) {\n throw new Error(`--setup is not supported by /sync ${command}.`);\n }\n if (options.yes && ![\"push\", \"pull\", \"sync\", \"rollback\", \"migrate-state\"].includes(command)) {\n throw new Error(`Confirmation/force options are not supported by /sync ${command}.`);\n }\n if (options.force && ![\"push\", \"pull\", \"sync\", \"rollback\"].includes(command)) {\n throw new Error(`Confirmation/force options are not supported by /sync ${command}.`);\n }\n if (options.stale && command !== \"unlock\") {\n throw new Error(`--stale is not supported by /sync ${command}.`);\n }\n const expectedValues = command === \"rollback\" || command === \"use\" ? 1 : 0;\n if (options.args.length !== expectedValues) {\n if (command === \"rollback\") throw new Error(\"Usage: /sync rollback <snapshot-id> [--yes] [--setup <name>]\");\n if (command === \"use\") throw new Error(\"Usage: /sync use <setup>\");\n throw new Error(`Unexpected argument for /sync ${command}: ${options.args.join(\" \")}`);\n }\n}\n\nexport function completeSyncArguments(argumentPrefix: string): CommandArgumentCompletion[] | null {\n const prefix = argumentPrefix.trimStart();\n if (prefix === \"\") return [...SYNC_COMMAND_COMPLETIONS];\n\n const trailingSpace = /\\s$/.test(prefix);\n const tokens = splitArgs(prefix);\n if (tokens.length === 0) return [...SYNC_COMMAND_COMPLETIONS];\n\n const [command] = tokens;\n if (tokens.length === 1 && !trailingSpace) {\n const matches = SYNC_COMMAND_COMPLETIONS.filter((item) => item.value.startsWith(command));\n return matches.length > 0 ? [...matches] : null;\n }\n\n const args = tokens.slice(1);\n if (command === \"use\") {\n if (args.length > 1 || (trailingSpace && args.length > 0)) return null;\n return completeSetupValue(prefix, trailingSpace ? \"\" : (args[0] ?? \"\"));\n }\n const setupFlagIndex = args.lastIndexOf(\"--setup\");\n if (setupFlagIndex >= 0 && setupFlagIndex === args.length - (trailingSpace ? 1 : 2)) {\n const currentSetup = trailingSpace ? \"\" : (args.at(-1) ?? \"\");\n if (!currentSetup.startsWith(\"-\")) return completeSetupValue(prefix, currentSetup);\n }\n\n const flagCompletions = SYNC_FLAG_COMPLETIONS[command];\n if (!flagCompletions) return null;\n\n const completedArgs = trailingSpace ? args : args.slice(0, -1);\n const completedValues = completedArgs.filter((arg) => !arg.startsWith(\"-\"));\n if (command === \"rollback\" ? completedValues.length > 1 : completedValues.length > 0) {\n return null;\n }\n\n const current = trailingSpace ? \"\" : (args.at(-1) ?? \"\");\n if (current && !current.startsWith(\"-\")) return null;\n\n const currentRaw = trailingSpace ? \"\" : (prefix.match(/\\S+$/)?.[0] ?? \"\");\n const completionPrefix = trailingSpace ? prefix : prefix.slice(0, prefix.length - currentRaw.length);\n const matches = flagCompletions.filter((item) => item.value.startsWith(current));\n return matches.length > 0 ? matches.map((item) => ({ ...item, value: `${completionPrefix}${item.value}` })) : null;\n}\n\nfunction completeSetupValue(prefix: string, current: string) {\n const currentRaw = current ? (prefix.match(/\\S+$/u)?.[0] ?? \"\") : \"\";\n const completionPrefix = currentRaw ? prefix.slice(0, prefix.length - currentRaw.length) : prefix;\n const matches = setupCompletionNames.filter((name) => name.startsWith(current));\n return matches.length > 0\n ? matches.map((name) => ({\n value: `${completionPrefix}${name}`,\n label: name,\n description: \"Sync setup\",\n }))\n : null;\n}\n\nexport function syncMenuOptions() {\n return SYNC_COMMANDS.map(({ name, description }) => `${name} \u2014 ${description}`);\n}\n\nexport function syncCommandFromMenuOption(option: string): SyncCommandName | undefined {\n return SYNC_COMMANDS.find(({ name, description }) => option === `${name} \u2014 ${description}`)?.name;\n}\n\nexport async function resolveSyncCommand(input: string, ctx: ExtensionCommandContext) {\n const [subcommand, ...rest] = splitArgs(input);\n if (subcommand) return { subcommand, rest };\n if (!ctx.hasUI) {\n ctx.ui.notify(usage(), \"info\");\n return undefined;\n }\n\n const selectedOption = await ctx.ui.select(\"pi-sync\", syncMenuOptions());\n const selected = selectedOption ? syncCommandFromMenuOption(selectedOption) : undefined;\n if (!selected) return undefined;\n if (selected !== \"rollback\") return { subcommand: selected, rest: [] };\n\n const target = (await ctx.ui.input(\"Rollback snapshot\", \"snapshot id\"))?.trim();\n if (!target) {\n ctx.ui.notify(\"Rollback cancelled.\", \"info\");\n return undefined;\n }\n return { subcommand: selected, rest: [target] };\n}\n\nexport function usage() {\n const commands = SYNC_COMMANDS.map(\n (command) => `${command.name}${\"usageSuffix\" in command ? command.usageSuffix : \"\"}`,\n ).join(\", \");\n return [\n \"Usage: /sync <command>\",\n `Commands: ${commands}`,\n `Automatic sync: ${AUTOMATIC_SYNC_DESCRIPTION}`,\n `Startup transfer: ${STARTUP_TRANSFER_DESCRIPTION}`,\n \"Automatic transfer at startup is a separate opt-in: one conflict-free established-baseline transfer at idle in TUI/RPC, with conditional/lease publication and no resource reload.\",\n \"Experimental Continuous sync is a separate default-Off opt-in in Settings. It requires Agent mode, monitors while Pi is open, and can incur recurring network/model costs. Safety blocks and durable automatic request limits remain.\",\n \"Settings: use /sync init or edit storage connections and sync setups in ~/.pi/agent/pi-sync.json (or the configured Pi agent directory). Version 1 and version 2 settings are unsupported and are never rewritten.\",\n ].join(\"\\n\");\n}\n"],
|
|
4
|
+
"sourcesContent": ["export const AUTOMATIC_SYNC_DESCRIPTION =\n \"This setup: check remote state once at startup in TUI/RPC. At shutdown, push all selected content only when sessions are included; reload skips that push. Saves apply to subsequent operations; a new check waits for the next session start. This does not enable startup transfer.\";\n\nexport const STARTUP_TRANSFER_DESCRIPTION =\n \"This setup: separate opt-in for one idle startup transfer in TUI/RPC. Requires an accepted baseline, matching remote included paths, and conditional or lease-protected publication (Git, verified WebDAV, or R2/S3 with verified conditional writes). May upload, replace, or remove selected files. Never reloads resources. Enabling applies next session start; opening Settings cancels pending work. Completed transfers are not undone.\";\n\nexport function startupTransferSummary(config: {\n automaticTransfer?: boolean;\n backend: { type: \"s3\" | \"git\" | \"webdav\" };\n}) {\n if (!config.automaticTransfer) return \"Off\";\n return config.backend.type === \"s3\"\n ? \"On (next idle startup; R2/S3 conditional-write verification required)\"\n : \"On (next idle startup; baseline and remote policy checks required)\";\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { AUTOMATIC_SYNC_DESCRIPTION, STARTUP_TRANSFER_DESCRIPTION } from \"../ui/sync-behavior.js\";\nimport type { CommandArgumentCompletion, CommandOptions } from \"./command-types.js\";\n\nconst YES_FLAG_COMPLETIONS: readonly CommandArgumentCompletion[] = [\n { value: \"--yes\", label: \"--yes\", description: \"Skip confirmation prompts\" },\n { value: \"-y\", label: \"-y\", description: \"Skip confirmation prompts\" },\n];\nexport const SYNC_COMMANDS = [\n { name: \"help\", description: \"Show command usage\" },\n { name: \"use\", description: \"Switch the current sync setup\", usageSuffix: \" <setup>\" },\n { name: \"init\", description: \"Create local config template\" },\n { name: \"config\", description: \"Show resolved configuration\" },\n { name: \"files\", description: \"Choose included content\" },\n { name: \"status\", description: \"Show sync status\" },\n { name: \"diff\", description: \"Show local/remote diff\" },\n { name: \"conflicts\", description: \"Review private unresolved conflict groups\" },\n { name: \"doctor\", description: \"Check config, secrets, and lock state\" },\n { name: \"push\", description: \"Upload local settings\" },\n { name: \"pull\", description: \"Apply remote settings\" },\n { name: \"sync\", description: \"Push or pull as needed\" },\n { name: \"history\", description: \"Show recent remote snapshots\" },\n { name: \"rollback\", description: \"Apply a previous snapshot\", usageSuffix: \" <snapshot>\" },\n { name: \"migrate-state\", description: \"Move legacy state into pi-sync/\" },\n { name: \"unlock\", description: \"Remove a stale local lock\", usageSuffix: \" --stale\" },\n] as const;\n\nexport type SyncCommandName = (typeof SYNC_COMMANDS)[number][\"name\"];\n\nconst SYNC_COMMAND_COMPLETIONS: readonly CommandArgumentCompletion[] = SYNC_COMMANDS.map(({ name, description }) => ({\n value: name,\n label: name,\n description,\n}));\nlet setupCompletionNames: string[] = [];\n\nexport function setSyncSetupCompletions(names: readonly string[]) {\n setupCompletionNames = [...new Set(names)].sort((left, right) => left.localeCompare(right));\n}\nconst SETUP_FLAG_COMPLETION = {\n value: \"--setup\",\n label: \"--setup\",\n description: \"Address a sync setup without switching\",\n} as const;\nconst SYNC_FLAG_COMPLETIONS: Record<string, readonly CommandArgumentCompletion[]> = {\n config: [SETUP_FLAG_COMPLETION],\n files: [SETUP_FLAG_COMPLETION],\n status: [SETUP_FLAG_COMPLETION],\n diff: [SETUP_FLAG_COMPLETION],\n conflicts: [SETUP_FLAG_COMPLETION],\n doctor: [SETUP_FLAG_COMPLETION],\n push: [\n ...YES_FLAG_COMPLETIONS,\n { value: \"--force\", label: \"--force\", description: \"Overwrite visible remote changes\" },\n SETUP_FLAG_COMPLETION,\n ],\n pull: [\n ...YES_FLAG_COMPLETIONS,\n { value: \"--force\", label: \"--force\", description: \"Overwrite local changes\" },\n SETUP_FLAG_COMPLETION,\n ],\n sync: [\n ...YES_FLAG_COMPLETIONS,\n { value: \"--force\", label: \"--force\", description: \"Resolve conflicts by forcing action\" },\n SETUP_FLAG_COMPLETION,\n ],\n history: [SETUP_FLAG_COMPLETION],\n rollback: [...YES_FLAG_COMPLETIONS, SETUP_FLAG_COMPLETION],\n \"migrate-state\": YES_FLAG_COMPLETIONS,\n unlock: [{ value: \"--stale\", label: \"--stale\", description: \"Remove only a stale lock\" }],\n};\n\nexport function splitArgs(input: string) {\n return input.match(/(?:[^\\s\"']+|\"[^\"]*\"|'[^']*')+/g)?.map((arg) => arg.replace(/^['\"]|['\"]$/g, \"\")) ?? [];\n}\n\nexport function parseOptions(args: string[]): CommandOptions {\n const values: string[] = [];\n let yes = false;\n let force = false;\n let stale = false;\n let setup: string | undefined;\n for (let index = 0; index < args.length; index += 1) {\n const arg = args[index];\n if (arg === \"--yes\" || arg === \"-y\") yes = true;\n else if (arg === \"--force\") force = true;\n else if (arg === \"--stale\") stale = true;\n else if (arg === \"--setup\") {\n const name = args[index + 1];\n if (!name || name.startsWith(\"-\")) throw new Error(\"--setup requires a sync setup name.\");\n if (setup !== undefined) throw new Error(\"--setup may be provided only once.\");\n setup = name;\n index += 1;\n } else if (arg.startsWith(\"-\")) {\n throw new Error(`Unknown sync option: ${arg}`);\n } else values.push(arg);\n }\n return {\n yes,\n force,\n stale,\n silent: false,\n reload: true,\n auto: false,\n ...(setup === undefined ? {} : { setup }),\n args: values,\n };\n}\n\nexport function validateCommandOptions(command: string, options: CommandOptions) {\n const setupAllowed = new Set([\n \"config\",\n \"files\",\n \"status\",\n \"diff\",\n \"conflicts\",\n \"doctor\",\n \"push\",\n \"pull\",\n \"sync\",\n \"history\",\n \"rollback\",\n ]);\n if (options.setup && !setupAllowed.has(command)) {\n throw new Error(`--setup is not supported by /sync ${command}.`);\n }\n if (options.yes && ![\"push\", \"pull\", \"sync\", \"rollback\", \"migrate-state\"].includes(command)) {\n throw new Error(`Confirmation/force options are not supported by /sync ${command}.`);\n }\n if (options.force && ![\"push\", \"pull\", \"sync\", \"rollback\"].includes(command)) {\n throw new Error(`Confirmation/force options are not supported by /sync ${command}.`);\n }\n if (options.stale && command !== \"unlock\") {\n throw new Error(`--stale is not supported by /sync ${command}.`);\n }\n const expectedValues = command === \"rollback\" || command === \"use\" ? 1 : 0;\n if (options.args.length !== expectedValues) {\n if (command === \"rollback\") throw new Error(\"Usage: /sync rollback <snapshot-id> [--yes] [--setup <name>]\");\n if (command === \"use\") throw new Error(\"Usage: /sync use <setup>\");\n throw new Error(`Unexpected argument for /sync ${command}: ${options.args.join(\" \")}`);\n }\n}\n\nexport function completeSyncArguments(argumentPrefix: string): CommandArgumentCompletion[] | null {\n const prefix = argumentPrefix.trimStart();\n if (prefix === \"\") return [...SYNC_COMMAND_COMPLETIONS];\n\n const trailingSpace = /\\s$/.test(prefix);\n const tokens = splitArgs(prefix);\n if (tokens.length === 0) return [...SYNC_COMMAND_COMPLETIONS];\n\n const [command] = tokens;\n if (tokens.length === 1 && !trailingSpace) {\n const matches = SYNC_COMMAND_COMPLETIONS.filter((item) => item.value.startsWith(command));\n return matches.length > 0 ? [...matches] : null;\n }\n\n const args = tokens.slice(1);\n if (command === \"use\") {\n if (args.length > 1 || (trailingSpace && args.length > 0)) return null;\n return completeSetupValue(prefix, trailingSpace ? \"\" : (args[0] ?? \"\"));\n }\n const setupFlagIndex = args.lastIndexOf(\"--setup\");\n if (setupFlagIndex >= 0 && setupFlagIndex === args.length - (trailingSpace ? 1 : 2)) {\n const currentSetup = trailingSpace ? \"\" : (args.at(-1) ?? \"\");\n if (!currentSetup.startsWith(\"-\")) return completeSetupValue(prefix, currentSetup);\n }\n\n const flagCompletions = SYNC_FLAG_COMPLETIONS[command];\n if (!flagCompletions) return null;\n\n const completedArgs = trailingSpace ? args : args.slice(0, -1);\n const completedValues = completedArgs.filter((arg) => !arg.startsWith(\"-\"));\n if (command === \"rollback\" ? completedValues.length > 1 : completedValues.length > 0) {\n return null;\n }\n\n const current = trailingSpace ? \"\" : (args.at(-1) ?? \"\");\n if (current && !current.startsWith(\"-\")) return null;\n\n const currentRaw = trailingSpace ? \"\" : (prefix.match(/\\S+$/)?.[0] ?? \"\");\n const completionPrefix = trailingSpace ? prefix : prefix.slice(0, prefix.length - currentRaw.length);\n const matches = flagCompletions.filter((item) => item.value.startsWith(current));\n return matches.length > 0 ? matches.map((item) => ({ ...item, value: `${completionPrefix}${item.value}` })) : null;\n}\n\nfunction completeSetupValue(prefix: string, current: string) {\n const currentRaw = current ? (prefix.match(/\\S+$/u)?.[0] ?? \"\") : \"\";\n const completionPrefix = currentRaw ? prefix.slice(0, prefix.length - currentRaw.length) : prefix;\n const matches = setupCompletionNames.filter((name) => name.startsWith(current));\n return matches.length > 0\n ? matches.map((name) => ({\n value: `${completionPrefix}${name}`,\n label: name,\n description: \"Sync setup\",\n }))\n : null;\n}\n\nexport function syncMenuOptions() {\n return SYNC_COMMANDS.map(({ name, description }) => `${name} \u2014 ${description}`);\n}\n\nexport function syncCommandFromMenuOption(option: string): SyncCommandName | undefined {\n return SYNC_COMMANDS.find(({ name, description }) => option === `${name} \u2014 ${description}`)?.name;\n}\n\nexport async function resolveSyncCommand(input: string, ctx: ExtensionCommandContext) {\n const [subcommand, ...rest] = splitArgs(input);\n if (subcommand) return { subcommand, rest };\n if (!ctx.hasUI) {\n ctx.ui.notify(usage(), \"info\");\n return undefined;\n }\n\n const selectedOption = await ctx.ui.select(\"pi-sync\", syncMenuOptions());\n const selected = selectedOption ? syncCommandFromMenuOption(selectedOption) : undefined;\n if (!selected) return undefined;\n if (selected !== \"rollback\") return { subcommand: selected, rest: [] };\n\n const target = (await ctx.ui.input(\"Rollback snapshot\", \"snapshot id\"))?.trim();\n if (!target) {\n ctx.ui.notify(\"Rollback cancelled.\", \"info\");\n return undefined;\n }\n return { subcommand: selected, rest: [target] };\n}\n\nexport function usage() {\n const commands = SYNC_COMMANDS.map(\n (command) => `${command.name}${\"usageSuffix\" in command ? command.usageSuffix : \"\"}`,\n ).join(\", \");\n return [\n \"Usage: /sync <command>\",\n `Commands: ${commands}`,\n `Automatic sync: ${AUTOMATIC_SYNC_DESCRIPTION}`,\n `Startup transfer: ${STARTUP_TRANSFER_DESCRIPTION}`,\n \"Automatic transfer at startup is a separate opt-in: one conflict-free established-baseline transfer at idle in TUI/RPC, with conditional/lease publication and no resource reload.\",\n \"Continuous sync is a separate default-Off opt-in in Settings. It requires Autonomous sync, monitors while Pi is open, and can incur recurring network/model costs. Safety blocks and durable automatic request limits remain.\",\n \"Settings: use /sync init or edit storage connections and sync setups in ~/.pi/agent/pi-sync.json (or the configured Pi agent directory). Version 1 and version 2 settings are unsupported and are never rewritten.\",\n ].join(\"\\n\");\n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": ["matches"]
|
|
7
7
|
}
|
|
@@ -356,7 +356,7 @@ function hasReservationCapacity(record, now) {
|
|
|
356
356
|
}
|
|
357
357
|
async function continuousStatusLines(config, clock = Date.now) {
|
|
358
358
|
if (!config.continuous) return ["Continuous sync: Off"];
|
|
359
|
-
if (!config.agentMode) return ["Continuous sync: paused; enable
|
|
359
|
+
if (!config.agentMode) return ["Continuous sync: paused; enable Autonomous sync first"];
|
|
360
360
|
try {
|
|
361
361
|
const binding = await continuousBinding(config);
|
|
362
362
|
const document = await readContinuousPrivateDocument(`${binding}.json`);
|
|
@@ -412,4 +412,4 @@ export {
|
|
|
412
412
|
reserveContinuousRequest,
|
|
413
413
|
continuousStatusLines
|
|
414
414
|
};
|
|
415
|
-
//# sourceMappingURL=chunk-
|
|
415
|
+
//# sourceMappingURL=chunk-S5OCYVPS.ts.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/sync/continuous-lease.ts", "../../src/sync/continuous-storage.ts", "../../src/sync/continuous-record.ts"],
|
|
4
|
-
"sourcesContent": ["import { randomUUID } from \"node:crypto\";\nimport { lstatSync, readFileSync, rmdirSync, type Stats, stat } from \"node:fs\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport lockfile from \"proper-lockfile\";\nimport { withLock } from \"../state/lock.js\";\nimport { LOCKFILE_FS_ADAPTER } from \"../state/lockfile-fs.js\";\nimport {\n continuousRoot,\n prepareContinuousRoot,\n readContinuousPrivate,\n writeContinuousPrivate,\n} from \"./continuous-storage.js\";\n\nconst STALE_MS = 30_000;\nconst localLeases = new Set<string>();\nconst futureGuards = new Map<string, { identity: string; since: number }>();\ninterface Owner {\n version: 1;\n id: string;\n pid: number;\n binding: string;\n}\nexport interface ContinuousLease {\n signal: AbortSignal;\n assert(): void;\n release(): Promise<void>;\n}\nfunction validOwner(value: unknown): value is Owner {\n if (!value || typeof value !== \"object\") return false;\n const owner = value as Owner;\n return (\n Object.keys(owner).sort().join(\",\") === \"binding,id,pid,version\" &&\n owner.version === 1 &&\n typeof owner.id === \"string\" &&\n /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/u.test(owner.id) &&\n Number.isSafeInteger(owner.pid) &&\n owner.pid > 0 &&\n owner.pid <= 2147483647 &&\n typeof owner.binding === \"string\" &&\n /^[a-f0-9]{64}$/u.test(owner.binding)\n );\n}\n\n/** Advisory only: never authority for a transfer or lease takeover. */\nexport async function continuousLeaseOwner(binding: string): Promise<string> {\n const owner = await readContinuousPrivate(\"owner.json\");\n if (owner === undefined) return \"Local scheduler lease: not observed; waiting for an eligible session\";\n if (!validOwner(owner)) throw new Error(\"Invalid continuous sync owner\");\n try {\n const guard = await fs.lstat(path.join(continuousRoot(), \"scheduler.lock\"));\n if (guard.isDirectory() && !guard.isSymbolicLink() && Date.now() - guard.mtimeMs <= STALE_MS)\n return `Local scheduler lease: observed for pid ${owner.pid}; ${owner.binding === binding ? \"this can be another session\" : \"another setup; this setup is standby\"}`;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n }\n return \"Local scheduler lease: not observed; waiting for an eligible session\";\n}\n\n/** Caller holds state-directory access during acquisition; the renewable guard prevents live migration. */\nexport async function acquireContinuousLease(binding: string): Promise<ContinuousLease | undefined> {\n await prepareContinuousRoot();\n const file = path.join(continuousRoot(), \"scheduler\");\n const guardPath = `${file}.lock`;\n if (localLeases.has(file)) return undefined;\n const previousOwner = await readContinuousPrivate(\"owner.json\");\n if (previousOwner !== undefined && !validOwner(previousOwner))\n throw new Error(\"Invalid continuous sync owner; evidence retained.\");\n if (localLeases.has(file)) return undefined;\n localLeases.add(file);\n const acquiredAt = performance.now();\n const ownerPath = path.join(continuousRoot(), \"owner.json\");\n const controller = new AbortController();\n const owner: Owner = { version: 1, id: randomUUID(), pid: process.pid, binding };\n let identity: { dev: number; ino: number } | undefined;\n let published = false;\n // proper-lockfile also uses rmdirSync at process exit. Fence both cleanup paths.\n const removeGuard = (target: string) => {\n if (identity) {\n const current = lstatSync(target);\n if (current.dev !== identity.dev || current.ino !== identity.ino) return;\n }\n let current: unknown;\n try {\n const record = lstatSync(ownerPath);\n if (\n !record.isFile() ||\n record.isSymbolicLink() ||\n record.nlink !== 1 ||\n record.size > 4096 ||\n (process.platform !== \"win32\" && record.mode & 0o077)\n )\n return;\n current = JSON.parse(readFileSync(ownerPath, \"utf8\"));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n }\n if (published && current === undefined) return;\n if (\n current !== undefined &&\n (!validOwner(current) ||\n (current.id !== owner.id && (published || current.id !== (previousOwner as Owner | undefined)?.id)))\n )\n return;\n rmdirSync(target);\n };\n const adapter = {\n ...LOCKFILE_FS_ADAPTER,\n stat: (target: string, callback: (error: NodeJS.ErrnoException | null, value?: Stats) => void) =>\n stat(target, (error, value) => {\n if (!error && value.mtimeMs > Date.now() + STALE_MS) {\n const identity = `${value.dev}:${value.ino}:${value.mtimeMs}`;\n const previous = futureGuards.get(target);\n if (!previous || previous.identity !== identity)\n futureGuards.set(target, { identity, since: performance.now() });\n else if (performance.now() - previous.since > STALE_MS) value.mtime = new Date(Date.now() - STALE_MS - 1);\n } else futureGuards.delete(target);\n callback(error, value);\n }),\n rmdirSync: removeGuard,\n rmdir: (target: string, callback: (error?: NodeJS.ErrnoException | null) => void) => {\n try {\n removeGuard(target);\n callback();\n } catch (error) {\n callback(error as NodeJS.ErrnoException);\n }\n },\n };\n let compromised = false;\n let unlock: () => Promise<void>;\n try {\n unlock = await lockfile.lock(file, {\n fs: adapter,\n realpath: false,\n stale: STALE_MS,\n update: 10_000,\n retries: 0,\n onCompromised: () => {\n compromised = true;\n controller.abort(new DOMException(\"Continuous sync ownership lost\", \"AbortError\"));\n },\n });\n } catch (error) {\n localLeases.delete(file);\n if ((error as NodeJS.ErrnoException).code === \"ELOCKED\") return undefined;\n throw error;\n }\n let released = false;\n const release = async () => {\n if (released) return;\n released = true;\n controller.abort(new DOMException(\"Continuous sync owner released\", \"AbortError\"));\n try {\n if (!compromised) await unlock();\n } finally {\n localLeases.delete(file);\n futureGuards.delete(guardPath);\n }\n };\n try {\n identity = await fs.lstat(guardPath);\n await withLock(\"continuous-owner\", async () => {\n const previous = await readContinuousPrivate(\"owner.json\");\n if (previous !== undefined && !validOwner(previous))\n throw new Error(\"Invalid continuous sync owner; evidence retained.\");\n if (\n (previous as Owner | undefined)?.id !== (previousOwner as Owner | undefined)?.id ||\n performance.now() - acquiredAt > STALE_MS\n )\n throw new Error(\"Continuous lease generation changed before publication.\");\n const current = lstatSync(guardPath);\n if (controller.signal.aborted || current.dev !== identity?.dev || current.ino !== identity.ino)\n throw new Error(\"Continuous lease changed before publication.\");\n await writeContinuousPrivate(\"owner.json\", owner);\n published = true;\n });\n const assert = () => {\n controller.signal.throwIfAborted();\n try {\n const root = lstatSync(continuousRoot());\n if (!root.isDirectory() || root.isSymbolicLink() || (process.platform !== \"win32\" && root.mode & 0o077))\n throw new Error(\"Unsafe lease root\");\n const stat = lstatSync(guardPath);\n if (\n stat.isSymbolicLink() ||\n !stat.isDirectory() ||\n stat.dev !== identity?.dev ||\n stat.ino !== identity.ino ||\n Date.now() - stat.mtimeMs > STALE_MS\n )\n throw new Error(\"Lease guard changed\");\n const record = lstatSync(ownerPath);\n if (\n !record.isFile() ||\n record.isSymbolicLink() ||\n record.nlink !== 1 ||\n record.size > 4096 ||\n (process.platform !== \"win32\" && record.mode & 0o077)\n )\n throw new Error(\"Unsafe owner record\");\n const value: unknown = JSON.parse(readFileSync(ownerPath, \"utf8\"));\n if (!validOwner(value) || value.id !== owner.id || value.binding !== binding || value.pid !== process.pid)\n throw new Error(\"Lease owner changed\");\n } catch {\n controller.abort(new DOMException(\"Continuous sync ownership lost\", \"AbortError\"));\n controller.signal.throwIfAborted();\n }\n };\n assert();\n return { signal: controller.signal, assert, release };\n } catch (error) {\n await release();\n throw error;\n }\n}\n", "import { createHash } from \"node:crypto\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { getAgentDir } from \"@earendil-works/pi-coding-agent\";\nimport { backendIdentityCoordinates } from \"../backends/backend-identity.js\";\nimport type { AnySyncConfig } from \"../settings/settings-types.js\";\nimport { writeJson } from \"../state/json-file.js\";\nimport { stateDir } from \"../state/state-directory.js\";\nimport { ensureStateDir } from \"../state/sync-state-store.js\";\n\nexport const CONTINUOUS_RECORD_MAX_BYTES = 131072;\n\nexport function hashContinuous(value: unknown) {\n return createHash(\"sha256\")\n .update(JSON.stringify(value) ?? \"null\")\n .digest(\"hex\");\n}\nexport async function continuousBinding(config: AnySyncConfig) {\n return hashContinuous([await fs.realpath(getAgentDir()), config.setupName, backendIdentityCoordinates(config)]);\n}\nexport function continuousRoot() {\n return path.join(stateDir(), \"continuous\");\n}\nexport async function prepareContinuousRoot() {\n await ensureStateDir();\n await fs.mkdir(continuousRoot(), { recursive: true, mode: 0o700 });\n await checkContinuousRoot();\n}\nexport async function checkContinuousRoot() {\n const stat = await fs.lstat(continuousRoot());\n if (!stat.isDirectory() || stat.isSymbolicLink() || (process.platform !== \"win32\" && stat.mode & 0o077))\n throw new Error(\"Unsafe continuous sync directory; evidence retained.\");\n}\nexport async function readContinuousPrivate(name: string): Promise<unknown> {\n return (await readContinuousPrivateDocument(name))?.value;\n}\n/** Read-only metadata; uses the same private-file checks as runtime reads. */\nexport async function readContinuousPrivateDocument(\n name: string,\n): Promise<{ value: unknown; bytes: number } | undefined> {\n try {\n await checkContinuousRoot();\n const file = path.join(continuousRoot(), name);\n const stat = await fs.lstat(file);\n if (\n !stat.isFile() ||\n stat.isSymbolicLink() ||\n stat.nlink !== 1 ||\n stat.size > CONTINUOUS_RECORD_MAX_BYTES ||\n (process.platform !== \"win32\" && stat.mode & 0o077)\n )\n throw new Error(\"Unsafe continuous sync record; evidence retained.\");\n const bytes = await fs.readFile(file);\n return { value: JSON.parse(bytes.toString(\"utf8\")), bytes: bytes.byteLength };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return undefined;\n throw error;\n }\n}\nexport async function writeContinuousPrivate(name: string, value: unknown) {\n await checkContinuousRoot();\n await readContinuousPrivate(name); // Never replace unsafe or malformed evidence.\n await writeJson(path.join(continuousRoot(), name), value, { maxBytes: CONTINUOUS_RECORD_MAX_BYTES });\n}\n", "import type { AnySyncConfig } from \"../settings/settings-types.js\";\nimport { withLock } from \"../state/lock.js\";\nimport { withStateDirectoryAccess } from \"../state/state-directory.js\";\nimport { ContinuousError, type ContinuousErrorKind } from \"./continuous-errors.js\";\nimport { type ContinuousLease, continuousLeaseOwner } from \"./continuous-lease.js\";\nimport {\n CONTINUOUS_RECORD_MAX_BYTES,\n continuousBinding,\n readContinuousPrivate,\n readContinuousPrivateDocument,\n writeContinuousPrivate,\n} from \"./continuous-storage.js\";\n\nexport const REQUEST_WINDOW_MS = 15 * 60_000;\nexport interface ContinuousRecord {\n version: 1;\n binding: string;\n pending: boolean;\n phase: \"waiting\" | \"syncing\" | \"retry\" | \"blocked\";\n next: number;\n failures: number;\n evidence?: string;\n recovery?: string;\n notice?: string;\n configuration?: string;\n error?: ContinuousErrorKind;\n checked?: number;\n transferred?: number;\n calls: { key: string; at: number }[];\n attempts: Record<string, number>;\n}\nconst digest = (value: unknown) => typeof value === \"string\" && /^[a-f0-9]{64}$/u.test(value);\nconst timestamp = (value: unknown) =>\n typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0 && value <= 8_640_000_000_000_000;\nexport function validateContinuousRecord(value: unknown, binding: string): asserts value is ContinuousRecord {\n const record = value as ContinuousRecord;\n if (\n !record ||\n typeof record !== \"object\" ||\n record.version !== 1 ||\n record.binding !== binding ||\n Object.keys(record).some(\n (key) =>\n ![\n \"version\",\n \"binding\",\n \"pending\",\n \"phase\",\n \"next\",\n \"failures\",\n \"evidence\",\n \"recovery\",\n \"notice\",\n \"configuration\",\n \"error\",\n \"checked\",\n \"transferred\",\n \"calls\",\n \"attempts\",\n ].includes(key),\n ) ||\n typeof record.pending !== \"boolean\" ||\n ![\"waiting\", \"syncing\", \"retry\", \"blocked\"].includes(record.phase) ||\n !timestamp(record.next) ||\n !timestamp(record.failures) ||\n record.failures > 30 ||\n (record.evidence !== undefined && !digest(record.evidence)) ||\n (record.recovery !== undefined && !digest(record.recovery)) ||\n (record.notice !== undefined && !digest(record.notice)) ||\n (record.configuration !== undefined && !digest(record.configuration)) ||\n (record.error !== undefined &&\n ![\n \"transient\",\n \"contention\",\n \"stale\",\n \"authentication\",\n \"storage\",\n \"unsafe\",\n \"model\",\n \"budget\",\n \"unknown\",\n ].includes(record.error)) ||\n (record.checked !== undefined && !timestamp(record.checked)) ||\n (record.transferred !== undefined && !timestamp(record.transferred)) ||\n !Array.isArray(record.calls) ||\n record.calls.length > 2 ||\n record.calls.some(\n (call) => !call || Object.keys(call).sort().join(\",\") !== \"at,key\" || !digest(call.key) || !timestamp(call.at),\n ) ||\n !record.attempts ||\n typeof record.attempts !== \"object\" ||\n Array.isArray(record.attempts) ||\n Object.entries(record.attempts).some(\n ([key, count]) => !digest(key) || !Number.isInteger(count) || count < 1 || count > 2,\n ) ||\n record.calls.some(\n (call) => (record.attempts[call.key] ?? 0) < record.calls.filter((other) => other.key === call.key).length,\n )\n )\n throw new Error(\"Invalid continuous sync state; evidence retained.\");\n}\nfunction emptyContinuousRecord(binding: string): ContinuousRecord {\n return { version: 1, binding, pending: true, phase: \"waiting\", next: 0, failures: 0, calls: [], attempts: {} };\n}\nexport async function readContinuousRecord(binding: string): Promise<ContinuousRecord> {\n const value = await readContinuousPrivate(`${binding}.json`);\n if (value === undefined) return emptyContinuousRecord(binding);\n validateContinuousRecord(value, binding);\n return value;\n}\nexport async function updateContinuousRecord<T>(\n binding: string,\n lease: ContinuousLease,\n update: (record: ContinuousRecord) => T,\n): Promise<T> {\n return withStateDirectoryAccess(() =>\n withLock(\"continuous-state\", async () => {\n lease.assert();\n const record = await readContinuousRecord(binding);\n lease.assert();\n const result = update(record);\n validateContinuousRecord(record, binding);\n lease.assert();\n await writeContinuousPrivate(`${binding}.json`, record);\n lease.assert();\n return result;\n }),\n );\n}\nexport function normalizeContinuousClock(record: ContinuousRecord, now: number) {\n // A backward wall-clock jump cannot grant more calls: retain them for a full window.\n record.calls = record.calls\n .map((call) => ({ ...call, at: Math.min(call.at, now) }))\n .filter((call) => now - call.at < REQUEST_WINDOW_MS);\n record.next = Math.min(record.next, now + (record.error === \"budget\" ? REQUEST_WINDOW_MS : 300_000));\n}\nexport async function reserveContinuousRequest(\n binding: string,\n lease: ContinuousLease,\n key: string,\n clock: () => number = Date.now,\n signal?: AbortSignal,\n) {\n signal?.throwIfAborted();\n if (!digest(key)) throw new Error(\"Invalid continuous candidate key.\");\n let failure: ContinuousError | undefined;\n await updateContinuousRecord(binding, lease, (record) => {\n signal?.throwIfAborted();\n const now = clock();\n signal?.throwIfAborted();\n normalizeContinuousClock(record, now);\n if ((record.attempts[key] ?? 0) >= 2)\n failure = new ContinuousError(\n \"model\",\n \"Automatic request limit reached for this evidence. Change the evidence or review /sync; Sync now does not reset this limit.\",\n );\n else if (record.calls.length >= 2)\n failure = new ContinuousError(\n \"budget\",\n \"Automatic request window is full.\",\n Math.max(0, (record.calls[0]?.at ?? now) + REQUEST_WINDOW_MS - now),\n );\n else {\n record.attempts[key] = (record.attempts[key] ?? 0) + 1;\n record.calls.push({ key, at: now });\n }\n });\n // Atomic publication is not interruptible. A reservation written before cancellation stays spent.\n signal?.throwIfAborted();\n if (failure) throw failure;\n}\n\nconst recoveryActions: Record<ContinuousErrorKind, string> = {\n transient: \"Wait for the scheduled retry. Check network and service availability if failures continue.\",\n contention: \"Wait for the active sync operation to finish. Do not remove a live lock.\",\n stale: \"Wait for a fresh inspection after the retry delay. Local or remote evidence changed.\",\n authentication: \"Repair storage or Pi model authentication, then reopen /sync. Do not share credentials.\",\n storage: \"Repair private-state permissions, free space or storage access. Retain accounting and recovery evidence.\",\n unsafe:\n \"Remove secrets or repair unsupported conflicts. Changed evidence is inspected again; review /sync if needed.\",\n model:\n \"Review conflict evidence and Pi model access. Sync now reuses cached refusals; a refusal needs changed evidence or a separately confirmed retry.\",\n budget:\n \"Wait for the window allowance shown above. Waiting does not restore exhausted candidates or accounting capacity.\",\n unknown:\n \"Review /sync diagnostics and reconcile pending recovery before retrying. Do not delete private evidence or blindly republish.\",\n};\n\nfunction serializedBytes(record: ContinuousRecord): number {\n // Keep this aligned with writeJson's private-document encoding.\n return Buffer.byteLength(`${JSON.stringify(record, null, \"\\t\")}\\n`);\n}\n\n/** Check space for one reservation without retaining or publishing the synthetic candidate. */\nfunction hasReservationCapacity(record: ContinuousRecord, now: number): boolean {\n const existing = Object.keys(record.attempts).find((key) => record.attempts[key] === 1);\n let key = existing ?? \"0\".repeat(64);\n if (!existing) {\n for (let index = 1; record.attempts[key] !== undefined; index++) key = index.toString(16).padStart(64, \"0\");\n }\n return (\n serializedBytes({\n ...record,\n calls: [...record.calls, { key, at: now }],\n attempts: { ...record.attempts, [key]: (record.attempts[key] ?? 0) + 1 },\n }) <= CONTINUOUS_RECORD_MAX_BYTES\n );\n}\n\n/** Read-only status: no directory creation, lease, mutation, request reservation or provider call. */\nexport async function continuousStatusLines(config: AnySyncConfig, clock: () => number = Date.now): Promise<string[]> {\n if (!config.continuous) return [\"Continuous sync: Off\"];\n if (!config.agentMode) return [\"Continuous sync: paused; enable Agent mode first\"];\n try {\n const binding = await continuousBinding(config);\n const document = await readContinuousPrivateDocument(`${binding}.json`);\n const record = document === undefined ? emptyContinuousRecord(binding) : document.value;\n validateContinuousRecord(record, binding);\n const bytes = serializedBytes(record);\n // Only this detached read is normalized. A Status read never publishes clock repairs or expires durable calls.\n const now = clock();\n normalizeContinuousClock(record, now);\n const spent = Object.values(record.attempts).filter((count) => count === 2).length;\n const eligible =\n record.calls.length < 2 ? now : Math.min(...record.calls.map((call) => call.at)) + REQUEST_WINDOW_MS;\n const capacityRecord = { ...record, calls: [...record.calls] };\n normalizeContinuousClock(capacityRecord, eligible);\n const available = hasReservationCapacity(capacityRecord, eligible);\n const owner = await continuousLeaseOwner(binding).catch(\n () => \"Local scheduler lease: private owner metadata unavailable; retain evidence and repair access\",\n );\n return [\n `Continuous sync: ${record.phase}${record.error ? ` (${record.error})` : \"\"}${document === undefined ? \"; no accounting record yet\" : \"\"}`,\n owner,\n \"Scheduler owner model: unavailable; the observing session's selected model is not proof of the owner's model.\",\n `Automatic requests (rolling 15 minutes, window only): ${record.calls.length}/2 used; ${2 - record.calls.length} remaining.`,\n `Next request eligibility: ${available ? (eligible === now ? \"now (window allowance)\" : `${new Date(eligible).toISOString()} (window allowance)`) : \"unavailable (accounting full)\"}. Candidate, capacity, ownership and safety checks still apply.`,\n `Spent candidates: ${spent} exhausted / ${Object.keys(record.attempts).length} tracked; 2 automatic requests per candidate. Expired windows do not clear this limit.`,\n `Accounting: ${bytes}/${CONTINUOUS_RECORD_MAX_BYTES} serialized bytes; ${Math.max(0, CONTINUOUS_RECORD_MAX_BYTES - bytes)} bytes free; ${document?.bytes ?? 0} bytes on disk${available ? \".\" : \"; full for another reservation.\"}`,\n ...(!available\n ? [\n \"Accounting recovery: pause Continuous sync and seek reviewed recovery. Do not delete accounting, prune candidates or reset limits to regain requests.\",\n ]\n : []),\n `Last successful background check: ${record.checked !== undefined ? new Date(record.checked).toISOString() : \"not yet checked\"}`,\n `Last successful background transfer: ${record.transferred !== undefined ? new Date(record.transferred).toISOString() : \"none\"}`,\n ...(record.phase === \"retry\" ? [`Next background attempt: ${new Date(record.next).toISOString()}`] : []),\n ...(record.error ? [`Recovery (${record.error}): ${recoveryActions[record.error]}`] : []),\n ...(record.phase === \"blocked\" && !record.error\n ? [\"Review /sync diagnostics and repair changed evidence. Retain private recovery state.\"]\n : []),\n \"Monitoring requires an eligible open Pi session. Status does not spend model requests or clear retry limits.\",\n ];\n } catch {\n return [\n \"Continuous sync: private state unavailable; usage, eligibility and accounting bytes cannot be verified.\",\n `Accounting capacity: ${CONTINUOUS_RECORD_MAX_BYTES} bytes; do not treat unavailable accounting as unused allowance.`,\n \"Recovery: pause Continuous sync, retain malformed, unknown or unsafe evidence, and repair private-state access. Do not delete accounting or reset limits.\",\n ];\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { randomUUID } from \"node:crypto\";\nimport { lstatSync, readFileSync, rmdirSync, type Stats, stat } from \"node:fs\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport lockfile from \"proper-lockfile\";\nimport { withLock } from \"../state/lock.js\";\nimport { LOCKFILE_FS_ADAPTER } from \"../state/lockfile-fs.js\";\nimport {\n continuousRoot,\n prepareContinuousRoot,\n readContinuousPrivate,\n writeContinuousPrivate,\n} from \"./continuous-storage.js\";\n\nconst STALE_MS = 30_000;\nconst localLeases = new Set<string>();\nconst futureGuards = new Map<string, { identity: string; since: number }>();\ninterface Owner {\n version: 1;\n id: string;\n pid: number;\n binding: string;\n}\nexport interface ContinuousLease {\n signal: AbortSignal;\n assert(): void;\n release(): Promise<void>;\n}\nfunction validOwner(value: unknown): value is Owner {\n if (!value || typeof value !== \"object\") return false;\n const owner = value as Owner;\n return (\n Object.keys(owner).sort().join(\",\") === \"binding,id,pid,version\" &&\n owner.version === 1 &&\n typeof owner.id === \"string\" &&\n /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/u.test(owner.id) &&\n Number.isSafeInteger(owner.pid) &&\n owner.pid > 0 &&\n owner.pid <= 2147483647 &&\n typeof owner.binding === \"string\" &&\n /^[a-f0-9]{64}$/u.test(owner.binding)\n );\n}\n\n/** Advisory only: never authority for a transfer or lease takeover. */\nexport async function continuousLeaseOwner(binding: string): Promise<string> {\n const owner = await readContinuousPrivate(\"owner.json\");\n if (owner === undefined) return \"Local scheduler lease: not observed; waiting for an eligible session\";\n if (!validOwner(owner)) throw new Error(\"Invalid continuous sync owner\");\n try {\n const guard = await fs.lstat(path.join(continuousRoot(), \"scheduler.lock\"));\n if (guard.isDirectory() && !guard.isSymbolicLink() && Date.now() - guard.mtimeMs <= STALE_MS)\n return `Local scheduler lease: observed for pid ${owner.pid}; ${owner.binding === binding ? \"this can be another session\" : \"another setup; this setup is standby\"}`;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n }\n return \"Local scheduler lease: not observed; waiting for an eligible session\";\n}\n\n/** Caller holds state-directory access during acquisition; the renewable guard prevents live migration. */\nexport async function acquireContinuousLease(binding: string): Promise<ContinuousLease | undefined> {\n await prepareContinuousRoot();\n const file = path.join(continuousRoot(), \"scheduler\");\n const guardPath = `${file}.lock`;\n if (localLeases.has(file)) return undefined;\n const previousOwner = await readContinuousPrivate(\"owner.json\");\n if (previousOwner !== undefined && !validOwner(previousOwner))\n throw new Error(\"Invalid continuous sync owner; evidence retained.\");\n if (localLeases.has(file)) return undefined;\n localLeases.add(file);\n const acquiredAt = performance.now();\n const ownerPath = path.join(continuousRoot(), \"owner.json\");\n const controller = new AbortController();\n const owner: Owner = { version: 1, id: randomUUID(), pid: process.pid, binding };\n let identity: { dev: number; ino: number } | undefined;\n let published = false;\n // proper-lockfile also uses rmdirSync at process exit. Fence both cleanup paths.\n const removeGuard = (target: string) => {\n if (identity) {\n const current = lstatSync(target);\n if (current.dev !== identity.dev || current.ino !== identity.ino) return;\n }\n let current: unknown;\n try {\n const record = lstatSync(ownerPath);\n if (\n !record.isFile() ||\n record.isSymbolicLink() ||\n record.nlink !== 1 ||\n record.size > 4096 ||\n (process.platform !== \"win32\" && record.mode & 0o077)\n )\n return;\n current = JSON.parse(readFileSync(ownerPath, \"utf8\"));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n }\n if (published && current === undefined) return;\n if (\n current !== undefined &&\n (!validOwner(current) ||\n (current.id !== owner.id && (published || current.id !== (previousOwner as Owner | undefined)?.id)))\n )\n return;\n rmdirSync(target);\n };\n const adapter = {\n ...LOCKFILE_FS_ADAPTER,\n stat: (target: string, callback: (error: NodeJS.ErrnoException | null, value?: Stats) => void) =>\n stat(target, (error, value) => {\n if (!error && value.mtimeMs > Date.now() + STALE_MS) {\n const identity = `${value.dev}:${value.ino}:${value.mtimeMs}`;\n const previous = futureGuards.get(target);\n if (!previous || previous.identity !== identity)\n futureGuards.set(target, { identity, since: performance.now() });\n else if (performance.now() - previous.since > STALE_MS) value.mtime = new Date(Date.now() - STALE_MS - 1);\n } else futureGuards.delete(target);\n callback(error, value);\n }),\n rmdirSync: removeGuard,\n rmdir: (target: string, callback: (error?: NodeJS.ErrnoException | null) => void) => {\n try {\n removeGuard(target);\n callback();\n } catch (error) {\n callback(error as NodeJS.ErrnoException);\n }\n },\n };\n let compromised = false;\n let unlock: () => Promise<void>;\n try {\n unlock = await lockfile.lock(file, {\n fs: adapter,\n realpath: false,\n stale: STALE_MS,\n update: 10_000,\n retries: 0,\n onCompromised: () => {\n compromised = true;\n controller.abort(new DOMException(\"Continuous sync ownership lost\", \"AbortError\"));\n },\n });\n } catch (error) {\n localLeases.delete(file);\n if ((error as NodeJS.ErrnoException).code === \"ELOCKED\") return undefined;\n throw error;\n }\n let released = false;\n const release = async () => {\n if (released) return;\n released = true;\n controller.abort(new DOMException(\"Continuous sync owner released\", \"AbortError\"));\n try {\n if (!compromised) await unlock();\n } finally {\n localLeases.delete(file);\n futureGuards.delete(guardPath);\n }\n };\n try {\n identity = await fs.lstat(guardPath);\n await withLock(\"continuous-owner\", async () => {\n const previous = await readContinuousPrivate(\"owner.json\");\n if (previous !== undefined && !validOwner(previous))\n throw new Error(\"Invalid continuous sync owner; evidence retained.\");\n if (\n (previous as Owner | undefined)?.id !== (previousOwner as Owner | undefined)?.id ||\n performance.now() - acquiredAt > STALE_MS\n )\n throw new Error(\"Continuous lease generation changed before publication.\");\n const current = lstatSync(guardPath);\n if (controller.signal.aborted || current.dev !== identity?.dev || current.ino !== identity.ino)\n throw new Error(\"Continuous lease changed before publication.\");\n await writeContinuousPrivate(\"owner.json\", owner);\n published = true;\n });\n const assert = () => {\n controller.signal.throwIfAborted();\n try {\n const root = lstatSync(continuousRoot());\n if (!root.isDirectory() || root.isSymbolicLink() || (process.platform !== \"win32\" && root.mode & 0o077))\n throw new Error(\"Unsafe lease root\");\n const stat = lstatSync(guardPath);\n if (\n stat.isSymbolicLink() ||\n !stat.isDirectory() ||\n stat.dev !== identity?.dev ||\n stat.ino !== identity.ino ||\n Date.now() - stat.mtimeMs > STALE_MS\n )\n throw new Error(\"Lease guard changed\");\n const record = lstatSync(ownerPath);\n if (\n !record.isFile() ||\n record.isSymbolicLink() ||\n record.nlink !== 1 ||\n record.size > 4096 ||\n (process.platform !== \"win32\" && record.mode & 0o077)\n )\n throw new Error(\"Unsafe owner record\");\n const value: unknown = JSON.parse(readFileSync(ownerPath, \"utf8\"));\n if (!validOwner(value) || value.id !== owner.id || value.binding !== binding || value.pid !== process.pid)\n throw new Error(\"Lease owner changed\");\n } catch {\n controller.abort(new DOMException(\"Continuous sync ownership lost\", \"AbortError\"));\n controller.signal.throwIfAborted();\n }\n };\n assert();\n return { signal: controller.signal, assert, release };\n } catch (error) {\n await release();\n throw error;\n }\n}\n", "import { createHash } from \"node:crypto\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { getAgentDir } from \"@earendil-works/pi-coding-agent\";\nimport { backendIdentityCoordinates } from \"../backends/backend-identity.js\";\nimport type { AnySyncConfig } from \"../settings/settings-types.js\";\nimport { writeJson } from \"../state/json-file.js\";\nimport { stateDir } from \"../state/state-directory.js\";\nimport { ensureStateDir } from \"../state/sync-state-store.js\";\n\nexport const CONTINUOUS_RECORD_MAX_BYTES = 131072;\n\nexport function hashContinuous(value: unknown) {\n return createHash(\"sha256\")\n .update(JSON.stringify(value) ?? \"null\")\n .digest(\"hex\");\n}\nexport async function continuousBinding(config: AnySyncConfig) {\n return hashContinuous([await fs.realpath(getAgentDir()), config.setupName, backendIdentityCoordinates(config)]);\n}\nexport function continuousRoot() {\n return path.join(stateDir(), \"continuous\");\n}\nexport async function prepareContinuousRoot() {\n await ensureStateDir();\n await fs.mkdir(continuousRoot(), { recursive: true, mode: 0o700 });\n await checkContinuousRoot();\n}\nexport async function checkContinuousRoot() {\n const stat = await fs.lstat(continuousRoot());\n if (!stat.isDirectory() || stat.isSymbolicLink() || (process.platform !== \"win32\" && stat.mode & 0o077))\n throw new Error(\"Unsafe continuous sync directory; evidence retained.\");\n}\nexport async function readContinuousPrivate(name: string): Promise<unknown> {\n return (await readContinuousPrivateDocument(name))?.value;\n}\n/** Read-only metadata; uses the same private-file checks as runtime reads. */\nexport async function readContinuousPrivateDocument(\n name: string,\n): Promise<{ value: unknown; bytes: number } | undefined> {\n try {\n await checkContinuousRoot();\n const file = path.join(continuousRoot(), name);\n const stat = await fs.lstat(file);\n if (\n !stat.isFile() ||\n stat.isSymbolicLink() ||\n stat.nlink !== 1 ||\n stat.size > CONTINUOUS_RECORD_MAX_BYTES ||\n (process.platform !== \"win32\" && stat.mode & 0o077)\n )\n throw new Error(\"Unsafe continuous sync record; evidence retained.\");\n const bytes = await fs.readFile(file);\n return { value: JSON.parse(bytes.toString(\"utf8\")), bytes: bytes.byteLength };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return undefined;\n throw error;\n }\n}\nexport async function writeContinuousPrivate(name: string, value: unknown) {\n await checkContinuousRoot();\n await readContinuousPrivate(name); // Never replace unsafe or malformed evidence.\n await writeJson(path.join(continuousRoot(), name), value, { maxBytes: CONTINUOUS_RECORD_MAX_BYTES });\n}\n", "import type { AnySyncConfig } from \"../settings/settings-types.js\";\nimport { withLock } from \"../state/lock.js\";\nimport { withStateDirectoryAccess } from \"../state/state-directory.js\";\nimport { ContinuousError, type ContinuousErrorKind } from \"./continuous-errors.js\";\nimport { type ContinuousLease, continuousLeaseOwner } from \"./continuous-lease.js\";\nimport {\n CONTINUOUS_RECORD_MAX_BYTES,\n continuousBinding,\n readContinuousPrivate,\n readContinuousPrivateDocument,\n writeContinuousPrivate,\n} from \"./continuous-storage.js\";\n\nexport const REQUEST_WINDOW_MS = 15 * 60_000;\nexport interface ContinuousRecord {\n version: 1;\n binding: string;\n pending: boolean;\n phase: \"waiting\" | \"syncing\" | \"retry\" | \"blocked\";\n next: number;\n failures: number;\n evidence?: string;\n recovery?: string;\n notice?: string;\n configuration?: string;\n error?: ContinuousErrorKind;\n checked?: number;\n transferred?: number;\n calls: { key: string; at: number }[];\n attempts: Record<string, number>;\n}\nconst digest = (value: unknown) => typeof value === \"string\" && /^[a-f0-9]{64}$/u.test(value);\nconst timestamp = (value: unknown) =>\n typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0 && value <= 8_640_000_000_000_000;\nexport function validateContinuousRecord(value: unknown, binding: string): asserts value is ContinuousRecord {\n const record = value as ContinuousRecord;\n if (\n !record ||\n typeof record !== \"object\" ||\n record.version !== 1 ||\n record.binding !== binding ||\n Object.keys(record).some(\n (key) =>\n ![\n \"version\",\n \"binding\",\n \"pending\",\n \"phase\",\n \"next\",\n \"failures\",\n \"evidence\",\n \"recovery\",\n \"notice\",\n \"configuration\",\n \"error\",\n \"checked\",\n \"transferred\",\n \"calls\",\n \"attempts\",\n ].includes(key),\n ) ||\n typeof record.pending !== \"boolean\" ||\n ![\"waiting\", \"syncing\", \"retry\", \"blocked\"].includes(record.phase) ||\n !timestamp(record.next) ||\n !timestamp(record.failures) ||\n record.failures > 30 ||\n (record.evidence !== undefined && !digest(record.evidence)) ||\n (record.recovery !== undefined && !digest(record.recovery)) ||\n (record.notice !== undefined && !digest(record.notice)) ||\n (record.configuration !== undefined && !digest(record.configuration)) ||\n (record.error !== undefined &&\n ![\n \"transient\",\n \"contention\",\n \"stale\",\n \"authentication\",\n \"storage\",\n \"unsafe\",\n \"model\",\n \"budget\",\n \"unknown\",\n ].includes(record.error)) ||\n (record.checked !== undefined && !timestamp(record.checked)) ||\n (record.transferred !== undefined && !timestamp(record.transferred)) ||\n !Array.isArray(record.calls) ||\n record.calls.length > 2 ||\n record.calls.some(\n (call) => !call || Object.keys(call).sort().join(\",\") !== \"at,key\" || !digest(call.key) || !timestamp(call.at),\n ) ||\n !record.attempts ||\n typeof record.attempts !== \"object\" ||\n Array.isArray(record.attempts) ||\n Object.entries(record.attempts).some(\n ([key, count]) => !digest(key) || !Number.isInteger(count) || count < 1 || count > 2,\n ) ||\n record.calls.some(\n (call) => (record.attempts[call.key] ?? 0) < record.calls.filter((other) => other.key === call.key).length,\n )\n )\n throw new Error(\"Invalid continuous sync state; evidence retained.\");\n}\nfunction emptyContinuousRecord(binding: string): ContinuousRecord {\n return { version: 1, binding, pending: true, phase: \"waiting\", next: 0, failures: 0, calls: [], attempts: {} };\n}\nexport async function readContinuousRecord(binding: string): Promise<ContinuousRecord> {\n const value = await readContinuousPrivate(`${binding}.json`);\n if (value === undefined) return emptyContinuousRecord(binding);\n validateContinuousRecord(value, binding);\n return value;\n}\nexport async function updateContinuousRecord<T>(\n binding: string,\n lease: ContinuousLease,\n update: (record: ContinuousRecord) => T,\n): Promise<T> {\n return withStateDirectoryAccess(() =>\n withLock(\"continuous-state\", async () => {\n lease.assert();\n const record = await readContinuousRecord(binding);\n lease.assert();\n const result = update(record);\n validateContinuousRecord(record, binding);\n lease.assert();\n await writeContinuousPrivate(`${binding}.json`, record);\n lease.assert();\n return result;\n }),\n );\n}\nexport function normalizeContinuousClock(record: ContinuousRecord, now: number) {\n // A backward wall-clock jump cannot grant more calls: retain them for a full window.\n record.calls = record.calls\n .map((call) => ({ ...call, at: Math.min(call.at, now) }))\n .filter((call) => now - call.at < REQUEST_WINDOW_MS);\n record.next = Math.min(record.next, now + (record.error === \"budget\" ? REQUEST_WINDOW_MS : 300_000));\n}\nexport async function reserveContinuousRequest(\n binding: string,\n lease: ContinuousLease,\n key: string,\n clock: () => number = Date.now,\n signal?: AbortSignal,\n) {\n signal?.throwIfAborted();\n if (!digest(key)) throw new Error(\"Invalid continuous candidate key.\");\n let failure: ContinuousError | undefined;\n await updateContinuousRecord(binding, lease, (record) => {\n signal?.throwIfAborted();\n const now = clock();\n signal?.throwIfAborted();\n normalizeContinuousClock(record, now);\n if ((record.attempts[key] ?? 0) >= 2)\n failure = new ContinuousError(\n \"model\",\n \"Automatic request limit reached for this evidence. Change the evidence or review /sync; Sync now does not reset this limit.\",\n );\n else if (record.calls.length >= 2)\n failure = new ContinuousError(\n \"budget\",\n \"Automatic request window is full.\",\n Math.max(0, (record.calls[0]?.at ?? now) + REQUEST_WINDOW_MS - now),\n );\n else {\n record.attempts[key] = (record.attempts[key] ?? 0) + 1;\n record.calls.push({ key, at: now });\n }\n });\n // Atomic publication is not interruptible. A reservation written before cancellation stays spent.\n signal?.throwIfAborted();\n if (failure) throw failure;\n}\n\nconst recoveryActions: Record<ContinuousErrorKind, string> = {\n transient: \"Wait for the scheduled retry. Check network and service availability if failures continue.\",\n contention: \"Wait for the active sync operation to finish. Do not remove a live lock.\",\n stale: \"Wait for a fresh inspection after the retry delay. Local or remote evidence changed.\",\n authentication: \"Repair storage or Pi model authentication, then reopen /sync. Do not share credentials.\",\n storage: \"Repair private-state permissions, free space or storage access. Retain accounting and recovery evidence.\",\n unsafe:\n \"Remove secrets or repair unsupported conflicts. Changed evidence is inspected again; review /sync if needed.\",\n model:\n \"Review conflict evidence and Pi model access. Sync now reuses cached refusals; a refusal needs changed evidence or a separately confirmed retry.\",\n budget:\n \"Wait for the window allowance shown above. Waiting does not restore exhausted candidates or accounting capacity.\",\n unknown:\n \"Review /sync diagnostics and reconcile pending recovery before retrying. Do not delete private evidence or blindly republish.\",\n};\n\nfunction serializedBytes(record: ContinuousRecord): number {\n // Keep this aligned with writeJson's private-document encoding.\n return Buffer.byteLength(`${JSON.stringify(record, null, \"\\t\")}\\n`);\n}\n\n/** Check space for one reservation without retaining or publishing the synthetic candidate. */\nfunction hasReservationCapacity(record: ContinuousRecord, now: number): boolean {\n const existing = Object.keys(record.attempts).find((key) => record.attempts[key] === 1);\n let key = existing ?? \"0\".repeat(64);\n if (!existing) {\n for (let index = 1; record.attempts[key] !== undefined; index++) key = index.toString(16).padStart(64, \"0\");\n }\n return (\n serializedBytes({\n ...record,\n calls: [...record.calls, { key, at: now }],\n attempts: { ...record.attempts, [key]: (record.attempts[key] ?? 0) + 1 },\n }) <= CONTINUOUS_RECORD_MAX_BYTES\n );\n}\n\n/** Read-only status: no directory creation, lease, mutation, request reservation or provider call. */\nexport async function continuousStatusLines(config: AnySyncConfig, clock: () => number = Date.now): Promise<string[]> {\n if (!config.continuous) return [\"Continuous sync: Off\"];\n if (!config.agentMode) return [\"Continuous sync: paused; enable Autonomous sync first\"];\n try {\n const binding = await continuousBinding(config);\n const document = await readContinuousPrivateDocument(`${binding}.json`);\n const record = document === undefined ? emptyContinuousRecord(binding) : document.value;\n validateContinuousRecord(record, binding);\n const bytes = serializedBytes(record);\n // Only this detached read is normalized. A Status read never publishes clock repairs or expires durable calls.\n const now = clock();\n normalizeContinuousClock(record, now);\n const spent = Object.values(record.attempts).filter((count) => count === 2).length;\n const eligible =\n record.calls.length < 2 ? now : Math.min(...record.calls.map((call) => call.at)) + REQUEST_WINDOW_MS;\n const capacityRecord = { ...record, calls: [...record.calls] };\n normalizeContinuousClock(capacityRecord, eligible);\n const available = hasReservationCapacity(capacityRecord, eligible);\n const owner = await continuousLeaseOwner(binding).catch(\n () => \"Local scheduler lease: private owner metadata unavailable; retain evidence and repair access\",\n );\n return [\n `Continuous sync: ${record.phase}${record.error ? ` (${record.error})` : \"\"}${document === undefined ? \"; no accounting record yet\" : \"\"}`,\n owner,\n \"Scheduler owner model: unavailable; the observing session's selected model is not proof of the owner's model.\",\n `Automatic requests (rolling 15 minutes, window only): ${record.calls.length}/2 used; ${2 - record.calls.length} remaining.`,\n `Next request eligibility: ${available ? (eligible === now ? \"now (window allowance)\" : `${new Date(eligible).toISOString()} (window allowance)`) : \"unavailable (accounting full)\"}. Candidate, capacity, ownership and safety checks still apply.`,\n `Spent candidates: ${spent} exhausted / ${Object.keys(record.attempts).length} tracked; 2 automatic requests per candidate. Expired windows do not clear this limit.`,\n `Accounting: ${bytes}/${CONTINUOUS_RECORD_MAX_BYTES} serialized bytes; ${Math.max(0, CONTINUOUS_RECORD_MAX_BYTES - bytes)} bytes free; ${document?.bytes ?? 0} bytes on disk${available ? \".\" : \"; full for another reservation.\"}`,\n ...(!available\n ? [\n \"Accounting recovery: pause Continuous sync and seek reviewed recovery. Do not delete accounting, prune candidates or reset limits to regain requests.\",\n ]\n : []),\n `Last successful background check: ${record.checked !== undefined ? new Date(record.checked).toISOString() : \"not yet checked\"}`,\n `Last successful background transfer: ${record.transferred !== undefined ? new Date(record.transferred).toISOString() : \"none\"}`,\n ...(record.phase === \"retry\" ? [`Next background attempt: ${new Date(record.next).toISOString()}`] : []),\n ...(record.error ? [`Recovery (${record.error}): ${recoveryActions[record.error]}`] : []),\n ...(record.phase === \"blocked\" && !record.error\n ? [\"Review /sync diagnostics and repair changed evidence. Retain private recovery state.\"]\n : []),\n \"Monitoring requires an eligible open Pi session. Status does not spend model requests or clear retry limits.\",\n ];\n } catch {\n return [\n \"Continuous sync: private state unavailable; usage, eligibility and accounting bytes cannot be verified.\",\n `Accounting capacity: ${CONTINUOUS_RECORD_MAX_BYTES} bytes; do not treat unavailable accounting as unused allowance.`,\n \"Recovery: pause Continuous sync, retain malformed, unknown or unsafe evidence, and repair private-state access. Do not delete accounting or reset limits.\",\n ];\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["fs", "path", "stat", "fs", "path", "current", "identity", "stat", "key"]
|
|
7
7
|
}
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
import {
|
|
17
17
|
AUTOMATIC_SYNC_DESCRIPTION,
|
|
18
18
|
setSyncSetupCompletions
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-QPC5HT3A.ts";
|
|
20
20
|
import {
|
|
21
21
|
safeTerminalText
|
|
22
22
|
} from "./chunk-AMJRUXFT.ts";
|
|
@@ -1031,4 +1031,4 @@ export {
|
|
|
1031
1031
|
showAddWebDavStorageProfile,
|
|
1032
1032
|
showEditWebDavStorageProfile
|
|
1033
1033
|
};
|
|
1034
|
-
//# sourceMappingURL=chunk-
|
|
1034
|
+
//# sourceMappingURL=chunk-U6GXGY5G.ts.map
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from "./chunk-3ST7RSYN.ts";
|
|
6
6
|
import {
|
|
7
7
|
setSyncStatus
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-YIPK23JW.ts";
|
|
9
9
|
import {
|
|
10
10
|
withLock
|
|
11
11
|
} from "./chunk-6O3EDBRL.ts";
|
|
@@ -29,9 +29,9 @@ async function withAgentSyncLock(ctx, options, run) {
|
|
|
29
29
|
if (!(error instanceof AgentResolutionRequired)) throw error;
|
|
30
30
|
request = error;
|
|
31
31
|
}
|
|
32
|
-
const { withAgentClaim, readAgentCandidate, saveAgentCandidate, replaceRefusedAgentCandidate } = await import("./agent-store-
|
|
33
|
-
const { parseAgentCandidate } = await import("./agent-candidate-
|
|
34
|
-
const { runAgentResolver } = await import("./agent-runner-
|
|
32
|
+
const { withAgentClaim, readAgentCandidate, saveAgentCandidate, replaceRefusedAgentCandidate } = await import("./agent-store-7GINKTS7.ts");
|
|
33
|
+
const { parseAgentCandidate } = await import("./agent-candidate-U2NU3GUX.ts");
|
|
34
|
+
const { runAgentResolver } = await import("./agent-runner-FCRV2Z75.ts");
|
|
35
35
|
return withAgentClaim(async (assertOwner) => {
|
|
36
36
|
const clearStatus = () => setSyncStatus(ctx, void 0);
|
|
37
37
|
const onAbort = () => {
|
|
@@ -56,7 +56,7 @@ async function withAgentSyncLock(ctx, options, run) {
|
|
|
56
56
|
signal?.throwIfAborted();
|
|
57
57
|
});
|
|
58
58
|
await validate();
|
|
59
|
-
setSyncStatus(ctx, "sync resolving");
|
|
59
|
+
setSyncStatus(ctx, "sync resolving", { activity: "resolving" });
|
|
60
60
|
const cached = await withLock("agent-cache-read", async () => {
|
|
61
61
|
await assertOwner();
|
|
62
62
|
options.signal?.throwIfAborted();
|
|
@@ -85,7 +85,7 @@ async function withAgentSyncLock(ctx, options, run) {
|
|
|
85
85
|
try {
|
|
86
86
|
candidate = parseAgentCandidate(raw, request.evidence);
|
|
87
87
|
} catch {
|
|
88
|
-
throw new ContinuousError("model", "
|
|
88
|
+
throw new ContinuousError("model", "Autonomous sync paused: invalid resolver output; evidence retained.");
|
|
89
89
|
}
|
|
90
90
|
if (retry && candidate.results.some((row) => "refuse" in row))
|
|
91
91
|
throw new ContinuousError("model", "The model refused again. The previous refusal was retained.");
|
|
@@ -126,7 +126,7 @@ async function withAgentSyncLock(ctx, options, run) {
|
|
|
126
126
|
request = error;
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
|
-
throw new ContinuousError("stale", "
|
|
129
|
+
throw new ContinuousError("stale", "Autonomous sync paused: content changed repeatedly; retry later.");
|
|
130
130
|
} finally {
|
|
131
131
|
options.signal?.removeEventListener("abort", onAbort);
|
|
132
132
|
if (!options.signal?.aborted) clearStatus();
|
|
@@ -137,4 +137,4 @@ async function withAgentSyncLock(ctx, options, run) {
|
|
|
137
137
|
export {
|
|
138
138
|
withAgentSyncLock
|
|
139
139
|
};
|
|
140
|
-
//# sourceMappingURL=chunk-
|
|
140
|
+
//# sourceMappingURL=chunk-WQMYV4DW.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/sync/agent-sync.ts"],
|
|
4
|
+
"sourcesContent": ["import type { ExtensionContext } from \"@earendil-works/pi-coding-agent\";\nimport type { CommandOptions } from \"../commands/command-types.js\";\nimport { withLock } from \"../state/lock.js\";\nimport { setSyncStatus } from \"../ui/sync-status.js\";\nimport { AGENT_MAX_ATTEMPTS } from \"./agent-policy.js\";\nimport { type AgentAcceptance, AgentResolutionRequired } from \"./agent-request.js\";\nimport { ContinuousError } from \"./continuous-errors.js\";\n\n/** All callers retain their existing state-directory access guard. Off stays lazy. */\nexport async function withAgentSyncLock<T>(\n ctx: ExtensionContext,\n options: CommandOptions,\n run: (options: CommandOptions) => Promise<T>,\n): Promise<T | \"cancelled\"> {\n let request: AgentResolutionRequired;\n const background = options.background;\n const retry = Boolean(options.agentRetryRefusal);\n if (retry && (options.auto || background || !ctx.hasUI || (ctx.mode !== \"tui\" && ctx.mode !== \"rpc\")))\n throw new Error(\"A refused-model retry requires a foreground TUI or RPC manager review.\");\n try {\n return await withLock(\"sync\", () => run(options));\n } catch (error) {\n if (!(error instanceof AgentResolutionRequired)) throw error;\n request = error;\n }\n const { withAgentClaim, readAgentCandidate, saveAgentCandidate, replaceRefusedAgentCandidate } = await import(\n \"./agent-store.js\"\n );\n const { parseAgentCandidate } = await import(\"./agent-candidate.js\");\n const { runAgentResolver } = await import(\"./agent-runner.js\");\n return withAgentClaim(async (assertOwner) => {\n const clearStatus = () => setSyncStatus(ctx, undefined);\n const onAbort = () => {\n try {\n clearStatus();\n } catch {\n /* UI can already be disposed. */\n }\n };\n options.signal?.addEventListener(\"abort\", onAbort, { once: true });\n try {\n options.signal?.throwIfAborted();\n for (let attempt = 0; attempt < AGENT_MAX_ATTEMPTS; attempt++) {\n let expectedRefusal: ReturnType<typeof parseAgentCandidate> | undefined;\n const validate = (signal = options.signal) =>\n withLock(\"agent-validate\", async () => {\n signal?.throwIfAborted();\n await assertOwner();\n signal?.throwIfAborted();\n if (\n expectedRefusal &&\n JSON.stringify(await readAgentCandidate(request.key)) !== JSON.stringify(expectedRefusal)\n )\n throw new Error(\"Cached refusal changed during review; reopen the manager.\");\n signal?.throwIfAborted();\n await request.validate(signal);\n signal?.throwIfAborted();\n });\n await validate();\n setSyncStatus(ctx, \"sync resolving\", { activity: \"resolving\" });\n const cached = await withLock(\"agent-cache-read\", async () => {\n await assertOwner();\n options.signal?.throwIfAborted();\n return readAgentCandidate(request.key);\n });\n options.signal?.throwIfAborted();\n if (retry) {\n if (cached === undefined)\n throw new Error(\"No eligible cached refusal for the current evidence. Use Sync now first.\");\n expectedRefusal = parseAgentCandidate(JSON.stringify(cached), request.evidence);\n if (!expectedRefusal.results.some((row) => \"refuse\" in row))\n throw new Error(\"The current cached result is not a refusal. Use Sync now.\");\n const { confirmAgentRefusalRetry } = await import(\"./agent-refusal-retry.js\");\n options.signal?.throwIfAborted();\n if (!(await confirmAgentRefusalRetry(ctx, options.setup, request.evidence, validate, options.signal)))\n return \"cancelled\" as const;\n }\n const raw =\n cached === undefined || retry\n ? await runAgentResolver(\n ctx,\n request.evidence,\n validate,\n options.signal,\n background ? (signal) => background.reserve(request.key, signal) : undefined,\n )\n : JSON.stringify(cached);\n let candidate: ReturnType<typeof parseAgentCandidate>;\n try {\n candidate = parseAgentCandidate(raw, request.evidence);\n } catch {\n throw new ContinuousError(\"model\", \"Autonomous sync paused: invalid resolver output; evidence retained.\");\n }\n if (retry && candidate.results.some((row) => \"refuse\" in row))\n throw new ContinuousError(\"model\", \"The model refused again. The previous refusal was retained.\");\n await validate();\n const previous = expectedRefusal;\n if (!previous)\n await withLock(\"agent-cache-save\", async () => {\n await assertOwner();\n options.signal?.throwIfAborted();\n await saveAgentCandidate(request.key, candidate);\n });\n let retryCacheCommitted = false;\n const acceptance: AgentAcceptance = {\n key: request.key,\n candidate,\n ...(previous\n ? {\n commitCandidate: async () => {\n if (retryCacheCommitted) return;\n await replaceRefusedAgentCandidate(request.key, previous, candidate, async () => {\n options.signal?.throwIfAborted();\n await assertOwner();\n await request.validate(options.signal);\n options.signal?.throwIfAborted();\n });\n retryCacheCommitted = true;\n },\n }\n : {}),\n };\n try {\n return await withLock(\"sync\", async () => {\n await assertOwner();\n options.signal?.throwIfAborted();\n return run({ ...options, agentAcceptance: acceptance });\n });\n } catch (error) {\n if (!(error instanceof AgentResolutionRequired)) throw error;\n if (retry) throw new ContinuousError(\"stale\", \"Reviewed refusal evidence changed; reopen the manager.\");\n request = error;\n }\n }\n throw new ContinuousError(\"stale\", \"Autonomous sync paused: content changed repeatedly; retry later.\");\n } finally {\n options.signal?.removeEventListener(\"abort\", onAbort);\n if (!options.signal?.aborted) clearStatus();\n }\n });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
|
|
3
3
|
import {
|
|
4
4
|
setSyncSetupCompletions
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-QPC5HT3A.ts";
|
|
6
6
|
import {
|
|
7
7
|
safeTerminalText
|
|
8
8
|
} from "./chunk-AMJRUXFT.ts";
|
|
@@ -124,4 +124,4 @@ export {
|
|
|
124
124
|
saveOnSwitch,
|
|
125
125
|
useSyncSetup
|
|
126
126
|
};
|
|
127
|
-
//# sourceMappingURL=chunk-
|
|
127
|
+
//# sourceMappingURL=chunk-XEODG2PE.ts.map
|