@zero-transfer/ssh 0.4.0 → 0.4.2

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/dist/index.d.mts CHANGED
@@ -835,7 +835,41 @@ interface TransferEngineOptions {
835
835
  /** Clock used for receipts and progress events. Defaults to `new Date()`. */
836
836
  now?: () => Date;
837
837
  }
838
- /** Executes transfer jobs and produces audit-friendly receipts. */
838
+ /**
839
+ * Executes transfer jobs and produces audit-friendly receipts.
840
+ *
841
+ * The engine is the lowest-level entry point in the transfer stack: it owns
842
+ * retry policy, attempt history, abort propagation, progress event
843
+ * normalization, and receipt construction. Most callers reach the engine
844
+ * indirectly through {@link runRoute}, {@link uploadFile}, {@link downloadFile},
845
+ * {@link copyBetween}, or {@link TransferQueue}; instantiate it directly when
846
+ * you need full control over execution semantics.
847
+ *
848
+ * @example Execute a single job with a custom executor
849
+ * ```ts
850
+ * import { TransferEngine, type TransferExecutor, type TransferJob } from "@zero-transfer/sdk";
851
+ *
852
+ * const engine = new TransferEngine();
853
+ *
854
+ * const executor: TransferExecutor = async ({ job, signal, onProgress }) => {
855
+ * onProgress?.({ jobId: job.id, bytesTransferred: 0 });
856
+ * // … perform the bytes here, honoring `signal` …
857
+ * return { jobId: job.id, bytesTransferred: 1234, completedAt: new Date() };
858
+ * };
859
+ *
860
+ * const job: TransferJob = {
861
+ * id: "manual-1",
862
+ * operation: "upload",
863
+ * source: { profile: localProfile, path: "./data.bin" },
864
+ * destination: { profile: s3Profile, path: "/data/data.bin" },
865
+ * };
866
+ *
867
+ * const receipt = await engine.execute(job, executor, {
868
+ * retry: { maxAttempts: 3, baseDelayMs: 250 },
869
+ * });
870
+ * console.log(receipt.attempts.length); // 1 on success
871
+ * ```
872
+ */
839
873
  declare class TransferEngine {
840
874
  private readonly now;
841
875
  /**
@@ -1586,8 +1620,20 @@ interface ClientDiagnostics {
1586
1620
  /**
1587
1621
  * Returns a redaction-safe snapshot of the providers registered with a client.
1588
1622
  *
1623
+ * Use this when rendering a setup screen, generating a support bundle, or
1624
+ * asserting in tests that the expected provider factories were registered.
1625
+ *
1589
1626
  * @param client - Transfer client to inspect.
1590
1627
  * @returns Provider id and capability snapshot tuples.
1628
+ *
1629
+ * @example List registered providers
1630
+ * ```ts
1631
+ * import { summarizeClientDiagnostics } from "@zero-transfer/sdk";
1632
+ *
1633
+ * for (const { id, capabilities } of summarizeClientDiagnostics(client).providers) {
1634
+ * console.log(`${id}: streaming=${capabilities.readStream} resume=${capabilities.resumeDownload}`);
1635
+ * }
1636
+ * ```
1591
1637
  */
1592
1638
  declare function summarizeClientDiagnostics(client: TransferClient): ClientDiagnostics;
1593
1639
  /** Per-step duration measurements collected by {@link runConnectionDiagnostics}. */
@@ -1640,8 +1686,36 @@ interface RunConnectionDiagnosticsOptions {
1640
1686
  /**
1641
1687
  * Connects to a profile, captures capability and listing samples, and returns a redaction-safe report.
1642
1688
  *
1689
+ * Useful for connectivity "ping" pages, smoke tests, and bug reports. Secrets
1690
+ * in the profile are redacted via {@link redactConnectionProfile} before being
1691
+ * returned. The session is always disconnected before the function returns,
1692
+ * including when probes throw.
1693
+ *
1643
1694
  * @param options - Diagnostic probe options.
1644
1695
  * @returns Diagnostic report including timings and any captured error.
1696
+ *
1697
+ * @example Probe an SFTP connection
1698
+ * ```ts
1699
+ * import { runConnectionDiagnostics } from "@zero-transfer/sdk";
1700
+ *
1701
+ * const report = await runConnectionDiagnostics({
1702
+ * client,
1703
+ * profile: {
1704
+ * host: "sftp.example.com",
1705
+ * provider: "sftp",
1706
+ * username: "deploy",
1707
+ * ssh: { privateKey: { path: "./keys/id_ed25519" } },
1708
+ * },
1709
+ * listPath: "/uploads",
1710
+ * });
1711
+ *
1712
+ * if (!report.ok) {
1713
+ * console.error("connection failed:", report.error);
1714
+ * } else {
1715
+ * console.log(`connect=${report.timings.connectMs}ms list=${report.timings.listMs}ms`);
1716
+ * console.log(report.sample); // up to 5 entries from /uploads
1717
+ * }
1718
+ * ```
1645
1719
  */
1646
1720
  declare function runConnectionDiagnostics(options: RunConnectionDiagnosticsOptions): Promise<ConnectionDiagnosticsResult>;
1647
1721
 
@@ -1748,8 +1822,29 @@ interface MemoryProviderOptions {
1748
1822
  /**
1749
1823
  * Creates a provider factory backed by deterministic in-memory fixture entries.
1750
1824
  *
1825
+ * Useful for tests and examples where you want a real `TransferSession` without
1826
+ * touching disk or the network. Entries are pre-seeded; mutations made through
1827
+ * the session are visible to subsequent operations on the same provider.
1828
+ *
1751
1829
  * @param options - Optional fixture entries to expose through the memory provider.
1752
1830
  * @returns Provider factory suitable for `createTransferClient({ providers: [...] })`.
1831
+ *
1832
+ * @example Seed entries and read them back
1833
+ * ```ts
1834
+ * import { createMemoryProviderFactory, createTransferClient } from "@zero-transfer/sdk";
1835
+ *
1836
+ * const client = createTransferClient({
1837
+ * providers: [createMemoryProviderFactory({
1838
+ * entries: [
1839
+ * { path: "/fixtures/hello.txt", content: "hello world" },
1840
+ * { path: "/fixtures/data.bin", content: new Uint8Array([1, 2, 3]) },
1841
+ * ],
1842
+ * })],
1843
+ * });
1844
+ *
1845
+ * const session = await client.connect({ host: "fixtures", provider: "memory" });
1846
+ * console.log(await session.fs.list("/fixtures"));
1847
+ * ```
1753
1848
  */
1754
1849
  declare function createMemoryProviderFactory(options?: MemoryProviderOptions): ProviderFactory;
1755
1850
 
@@ -2487,9 +2582,47 @@ interface TransferPlanSummary {
2487
2582
  /** Counts grouped by action. */
2488
2583
  actions: Record<string, number>;
2489
2584
  }
2490
- /** Creates a transfer plan from dry-run planning input. */
2585
+ /**
2586
+ * Creates a transfer plan from dry-run planning input.
2587
+ *
2588
+ * Plans are immutable, structured descriptions of intended work. Pair with
2589
+ * {@link createSyncPlan} or {@link createAtomicDeployPlan} for end-to-end
2590
+ * planning, or build steps by hand when you need full control. Pass the plan
2591
+ * to {@link createTransferJobsFromPlan} to materialize executable jobs.
2592
+ *
2593
+ * @example Build a plan with two upload steps and inspect it
2594
+ * ```ts
2595
+ * import { createTransferPlan, summarizeTransferPlan } from "@zero-transfer/sdk";
2596
+ *
2597
+ * const plan = createTransferPlan({
2598
+ * id: "manual-batch",
2599
+ * steps: [
2600
+ * { action: "upload", source: "./a.bin", destination: "/lake/a.bin", expectedBytes: 1024 },
2601
+ * { action: "upload", source: "./b.bin", destination: "/lake/b.bin", expectedBytes: 2048 },
2602
+ * ],
2603
+ * });
2604
+ *
2605
+ * console.table(summarizeTransferPlan(plan));
2606
+ * ```
2607
+ */
2491
2608
  declare function createTransferPlan(input: TransferPlanInput): TransferPlan;
2492
- /** Summarizes a transfer plan for diagnostics, previews, and tests. */
2609
+ /**
2610
+ * Summarizes a transfer plan for diagnostics, previews, and tests.
2611
+ *
2612
+ * Returns aggregate counts (total / executable / skipped / destructive),
2613
+ * total expected bytes, and a per-action histogram. Useful for printing a
2614
+ * one-line plan summary before executing or for asserting plan shape in
2615
+ * tests.
2616
+ *
2617
+ * @example Print a plan preview
2618
+ * ```ts
2619
+ * import { summarizeTransferPlan } from "@zero-transfer/sdk";
2620
+ *
2621
+ * const summary = summarizeTransferPlan(plan);
2622
+ * console.log(`${summary.executableSteps} steps, ${summary.totalExpectedBytes} bytes total`);
2623
+ * console.log("Actions:", summary.actions);
2624
+ * ```
2625
+ */
2493
2626
  declare function summarizeTransferPlan(plan: TransferPlan): TransferPlanSummary;
2494
2627
  /** Converts executable plan steps into transfer jobs while preserving order. */
2495
2628
  declare function createTransferJobsFromPlan(plan: TransferPlan): TransferJob[];
@@ -2566,7 +2699,41 @@ interface TransferQueueSummary {
2566
2699
  /** Failed queue items in queue order. */
2567
2700
  failures: TransferQueueItem[];
2568
2701
  }
2569
- /** Minimal transfer queue with concurrency, pause/resume, cancellation, and drain summaries. */
2702
+ /**
2703
+ * Minimal transfer queue with concurrency, pause/resume, cancellation, and drain summaries.
2704
+ *
2705
+ * Wrap a {@link TransferEngine} with a queue when you need to run many transfers
2706
+ * concurrently with bounded parallelism, observe per-job progress, or drive
2707
+ * a UI from a single source of truth. Items are FIFO; failures and successes
2708
+ * are surfaced via observers and in the final {@link TransferQueueSummary}.
2709
+ *
2710
+ * @example Run a batch of uploads with concurrency=4
2711
+ * ```ts
2712
+ * import {
2713
+ * TransferQueue,
2714
+ * createProviderTransferExecutor,
2715
+ * } from "@zero-transfer/sdk";
2716
+ *
2717
+ * const queue = new TransferQueue({
2718
+ * concurrency: 4,
2719
+ * executor: createProviderTransferExecutor({ client }),
2720
+ * onProgress: (e) => console.log(`${e.jobId}: ${e.bytesTransferred}`),
2721
+ * onError: (item, err) => console.error(`${item.job.id} failed`, err),
2722
+ * });
2723
+ *
2724
+ * for (const file of files) {
2725
+ * queue.enqueue({
2726
+ * id: file.name,
2727
+ * operation: "upload",
2728
+ * source: { profile: localProfile, path: file.path },
2729
+ * destination: { profile: s3Profile, path: `/lake/${file.name}` },
2730
+ * });
2731
+ * }
2732
+ *
2733
+ * const summary = await queue.drain();
2734
+ * console.log(`Completed ${summary.completed} / ${summary.total}`);
2735
+ * ```
2736
+ */
2570
2737
  declare class TransferQueue {
2571
2738
  private readonly engine;
2572
2739
  private readonly items;
@@ -2846,6 +3013,26 @@ interface DiffRemoteTreesOptions {
2846
3013
  * @param destinationPath - Destination-side root path being compared.
2847
3014
  * @param options - Optional comparison controls.
2848
3015
  * @returns Diff result containing entries and a summary.
3016
+ *
3017
+ * @example Diff two SFTP subtrees and feed the result into createSyncPlan
3018
+ * ```ts
3019
+ * import { createSyncPlan, diffRemoteTrees } from "@zero-transfer/sdk";
3020
+ *
3021
+ * const diff = await diffRemoteTrees(
3022
+ * srcSession.fs, "/exports",
3023
+ * dstSession.fs, "/exports",
3024
+ * { compareUniqueId: true },
3025
+ * );
3026
+ *
3027
+ * console.log(diff.summary); // { added, removed, changed, unchanged }
3028
+ *
3029
+ * const plan = createSyncPlan({
3030
+ * id: "exports-sync",
3031
+ * diff,
3032
+ * source: { provider: "sftp", rootPath: "/exports" },
3033
+ * destination: { provider: "sftp", rootPath: "/exports" },
3034
+ * });
3035
+ * ```
2849
3036
  */
2850
3037
  declare function diffRemoteTrees(source: RemoteFileSystem, sourcePath: string, destination: RemoteFileSystem, destinationPath: string, options?: DiffRemoteTreesOptions): Promise<RemoteTreeDiff>;
2851
3038
 
@@ -2917,6 +3104,31 @@ interface CreateSyncPlanOptions {
2917
3104
  * @param options - Inputs and policies that shape the plan.
2918
3105
  * @returns Transfer plan ready for `createTransferJobsFromPlan` or queue execution.
2919
3106
  * @throws {@link ConfigurationError} When `conflictPolicy: "error"` encounters a conflict.
3107
+ *
3108
+ * @example Mirror SFTP → S3 with deletes
3109
+ * ```ts
3110
+ * import {
3111
+ * createSyncPlan,
3112
+ * diffRemoteTrees,
3113
+ * summarizeTransferPlan,
3114
+ * } from "@zero-transfer/sdk";
3115
+ *
3116
+ * const diff = await diffRemoteTrees(
3117
+ * srcSession.fs, "/dist",
3118
+ * dstSession.fs, "/releases/current",
3119
+ * );
3120
+ *
3121
+ * const plan = createSyncPlan({
3122
+ * id: "release-mirror",
3123
+ * diff,
3124
+ * source: { provider: "sftp", rootPath: "/dist" },
3125
+ * destination: { provider: "s3", rootPath: "/releases/current" },
3126
+ * deletePolicy: "mirror",
3127
+ * conflictPolicy: "overwrite",
3128
+ * });
3129
+ *
3130
+ * console.table(summarizeTransferPlan(plan));
3131
+ * ```
2920
3132
  */
2921
3133
  declare function createSyncPlan(options: CreateSyncPlanOptions): TransferPlan;
2922
3134
 
@@ -3032,9 +3244,39 @@ interface CreateAtomicDeployPlanOptions {
3032
3244
  /**
3033
3245
  * Builds an {@link AtomicDeployPlan} that stages a release, swaps it live, and prunes old releases.
3034
3246
  *
3247
+ * The plan describes a blue/green-style deploy:
3248
+ * 1. Upload to a timestamped staging directory under `<destination>/.releases/`.
3249
+ * 2. Atomically swap the `current` symlink/rename to point at the new release.
3250
+ * 3. Optionally prune old releases beyond `retain`.
3251
+ *
3252
+ * No I/O is performed — the host executes the plan steps. Pair with
3253
+ * {@link createTransferPlan} or {@link createTransferJobsFromPlan} to execute.
3254
+ *
3035
3255
  * @param options - Inputs and policies that shape the deploy.
3036
3256
  * @returns Structured deploy plan ready for execution by the calling host.
3037
3257
  * @throws {@link ConfigurationError} When `retain` is less than `1` or the destination root is empty.
3258
+ *
3259
+ * @example Plan a release with rollback path
3260
+ * ```ts
3261
+ * import { createAtomicDeployPlan } from "@zero-transfer/sdk";
3262
+ *
3263
+ * const plan = createAtomicDeployPlan({
3264
+ * id: "web-2026-04-28",
3265
+ * source: { rootPath: "./dist" },
3266
+ * destination: {
3267
+ * profile: { host: "web1.example.com", provider: "sftp", username: "deploy" },
3268
+ * rootPath: "/srv/www",
3269
+ * },
3270
+ * retain: 5,
3271
+ * existingReleases: [
3272
+ * "/srv/www/.releases/2026-04-21T00-00-00Z",
3273
+ * "/srv/www/.releases/2026-04-14T00-00-00Z",
3274
+ * ],
3275
+ * });
3276
+ *
3277
+ * console.log(plan.swap); // staging → current rename
3278
+ * console.log(plan.prune); // releases scheduled for removal
3279
+ * ```
3038
3280
  */
3039
3281
  declare function createAtomicDeployPlan(options: CreateAtomicDeployPlanOptions): AtomicDeployPlan;
3040
3282
 
package/dist/index.d.ts CHANGED
@@ -835,7 +835,41 @@ interface TransferEngineOptions {
835
835
  /** Clock used for receipts and progress events. Defaults to `new Date()`. */
836
836
  now?: () => Date;
837
837
  }
838
- /** Executes transfer jobs and produces audit-friendly receipts. */
838
+ /**
839
+ * Executes transfer jobs and produces audit-friendly receipts.
840
+ *
841
+ * The engine is the lowest-level entry point in the transfer stack: it owns
842
+ * retry policy, attempt history, abort propagation, progress event
843
+ * normalization, and receipt construction. Most callers reach the engine
844
+ * indirectly through {@link runRoute}, {@link uploadFile}, {@link downloadFile},
845
+ * {@link copyBetween}, or {@link TransferQueue}; instantiate it directly when
846
+ * you need full control over execution semantics.
847
+ *
848
+ * @example Execute a single job with a custom executor
849
+ * ```ts
850
+ * import { TransferEngine, type TransferExecutor, type TransferJob } from "@zero-transfer/sdk";
851
+ *
852
+ * const engine = new TransferEngine();
853
+ *
854
+ * const executor: TransferExecutor = async ({ job, signal, onProgress }) => {
855
+ * onProgress?.({ jobId: job.id, bytesTransferred: 0 });
856
+ * // … perform the bytes here, honoring `signal` …
857
+ * return { jobId: job.id, bytesTransferred: 1234, completedAt: new Date() };
858
+ * };
859
+ *
860
+ * const job: TransferJob = {
861
+ * id: "manual-1",
862
+ * operation: "upload",
863
+ * source: { profile: localProfile, path: "./data.bin" },
864
+ * destination: { profile: s3Profile, path: "/data/data.bin" },
865
+ * };
866
+ *
867
+ * const receipt = await engine.execute(job, executor, {
868
+ * retry: { maxAttempts: 3, baseDelayMs: 250 },
869
+ * });
870
+ * console.log(receipt.attempts.length); // 1 on success
871
+ * ```
872
+ */
839
873
  declare class TransferEngine {
840
874
  private readonly now;
841
875
  /**
@@ -1586,8 +1620,20 @@ interface ClientDiagnostics {
1586
1620
  /**
1587
1621
  * Returns a redaction-safe snapshot of the providers registered with a client.
1588
1622
  *
1623
+ * Use this when rendering a setup screen, generating a support bundle, or
1624
+ * asserting in tests that the expected provider factories were registered.
1625
+ *
1589
1626
  * @param client - Transfer client to inspect.
1590
1627
  * @returns Provider id and capability snapshot tuples.
1628
+ *
1629
+ * @example List registered providers
1630
+ * ```ts
1631
+ * import { summarizeClientDiagnostics } from "@zero-transfer/sdk";
1632
+ *
1633
+ * for (const { id, capabilities } of summarizeClientDiagnostics(client).providers) {
1634
+ * console.log(`${id}: streaming=${capabilities.readStream} resume=${capabilities.resumeDownload}`);
1635
+ * }
1636
+ * ```
1591
1637
  */
1592
1638
  declare function summarizeClientDiagnostics(client: TransferClient): ClientDiagnostics;
1593
1639
  /** Per-step duration measurements collected by {@link runConnectionDiagnostics}. */
@@ -1640,8 +1686,36 @@ interface RunConnectionDiagnosticsOptions {
1640
1686
  /**
1641
1687
  * Connects to a profile, captures capability and listing samples, and returns a redaction-safe report.
1642
1688
  *
1689
+ * Useful for connectivity "ping" pages, smoke tests, and bug reports. Secrets
1690
+ * in the profile are redacted via {@link redactConnectionProfile} before being
1691
+ * returned. The session is always disconnected before the function returns,
1692
+ * including when probes throw.
1693
+ *
1643
1694
  * @param options - Diagnostic probe options.
1644
1695
  * @returns Diagnostic report including timings and any captured error.
1696
+ *
1697
+ * @example Probe an SFTP connection
1698
+ * ```ts
1699
+ * import { runConnectionDiagnostics } from "@zero-transfer/sdk";
1700
+ *
1701
+ * const report = await runConnectionDiagnostics({
1702
+ * client,
1703
+ * profile: {
1704
+ * host: "sftp.example.com",
1705
+ * provider: "sftp",
1706
+ * username: "deploy",
1707
+ * ssh: { privateKey: { path: "./keys/id_ed25519" } },
1708
+ * },
1709
+ * listPath: "/uploads",
1710
+ * });
1711
+ *
1712
+ * if (!report.ok) {
1713
+ * console.error("connection failed:", report.error);
1714
+ * } else {
1715
+ * console.log(`connect=${report.timings.connectMs}ms list=${report.timings.listMs}ms`);
1716
+ * console.log(report.sample); // up to 5 entries from /uploads
1717
+ * }
1718
+ * ```
1645
1719
  */
1646
1720
  declare function runConnectionDiagnostics(options: RunConnectionDiagnosticsOptions): Promise<ConnectionDiagnosticsResult>;
1647
1721
 
@@ -1748,8 +1822,29 @@ interface MemoryProviderOptions {
1748
1822
  /**
1749
1823
  * Creates a provider factory backed by deterministic in-memory fixture entries.
1750
1824
  *
1825
+ * Useful for tests and examples where you want a real `TransferSession` without
1826
+ * touching disk or the network. Entries are pre-seeded; mutations made through
1827
+ * the session are visible to subsequent operations on the same provider.
1828
+ *
1751
1829
  * @param options - Optional fixture entries to expose through the memory provider.
1752
1830
  * @returns Provider factory suitable for `createTransferClient({ providers: [...] })`.
1831
+ *
1832
+ * @example Seed entries and read them back
1833
+ * ```ts
1834
+ * import { createMemoryProviderFactory, createTransferClient } from "@zero-transfer/sdk";
1835
+ *
1836
+ * const client = createTransferClient({
1837
+ * providers: [createMemoryProviderFactory({
1838
+ * entries: [
1839
+ * { path: "/fixtures/hello.txt", content: "hello world" },
1840
+ * { path: "/fixtures/data.bin", content: new Uint8Array([1, 2, 3]) },
1841
+ * ],
1842
+ * })],
1843
+ * });
1844
+ *
1845
+ * const session = await client.connect({ host: "fixtures", provider: "memory" });
1846
+ * console.log(await session.fs.list("/fixtures"));
1847
+ * ```
1753
1848
  */
1754
1849
  declare function createMemoryProviderFactory(options?: MemoryProviderOptions): ProviderFactory;
1755
1850
 
@@ -2487,9 +2582,47 @@ interface TransferPlanSummary {
2487
2582
  /** Counts grouped by action. */
2488
2583
  actions: Record<string, number>;
2489
2584
  }
2490
- /** Creates a transfer plan from dry-run planning input. */
2585
+ /**
2586
+ * Creates a transfer plan from dry-run planning input.
2587
+ *
2588
+ * Plans are immutable, structured descriptions of intended work. Pair with
2589
+ * {@link createSyncPlan} or {@link createAtomicDeployPlan} for end-to-end
2590
+ * planning, or build steps by hand when you need full control. Pass the plan
2591
+ * to {@link createTransferJobsFromPlan} to materialize executable jobs.
2592
+ *
2593
+ * @example Build a plan with two upload steps and inspect it
2594
+ * ```ts
2595
+ * import { createTransferPlan, summarizeTransferPlan } from "@zero-transfer/sdk";
2596
+ *
2597
+ * const plan = createTransferPlan({
2598
+ * id: "manual-batch",
2599
+ * steps: [
2600
+ * { action: "upload", source: "./a.bin", destination: "/lake/a.bin", expectedBytes: 1024 },
2601
+ * { action: "upload", source: "./b.bin", destination: "/lake/b.bin", expectedBytes: 2048 },
2602
+ * ],
2603
+ * });
2604
+ *
2605
+ * console.table(summarizeTransferPlan(plan));
2606
+ * ```
2607
+ */
2491
2608
  declare function createTransferPlan(input: TransferPlanInput): TransferPlan;
2492
- /** Summarizes a transfer plan for diagnostics, previews, and tests. */
2609
+ /**
2610
+ * Summarizes a transfer plan for diagnostics, previews, and tests.
2611
+ *
2612
+ * Returns aggregate counts (total / executable / skipped / destructive),
2613
+ * total expected bytes, and a per-action histogram. Useful for printing a
2614
+ * one-line plan summary before executing or for asserting plan shape in
2615
+ * tests.
2616
+ *
2617
+ * @example Print a plan preview
2618
+ * ```ts
2619
+ * import { summarizeTransferPlan } from "@zero-transfer/sdk";
2620
+ *
2621
+ * const summary = summarizeTransferPlan(plan);
2622
+ * console.log(`${summary.executableSteps} steps, ${summary.totalExpectedBytes} bytes total`);
2623
+ * console.log("Actions:", summary.actions);
2624
+ * ```
2625
+ */
2493
2626
  declare function summarizeTransferPlan(plan: TransferPlan): TransferPlanSummary;
2494
2627
  /** Converts executable plan steps into transfer jobs while preserving order. */
2495
2628
  declare function createTransferJobsFromPlan(plan: TransferPlan): TransferJob[];
@@ -2566,7 +2699,41 @@ interface TransferQueueSummary {
2566
2699
  /** Failed queue items in queue order. */
2567
2700
  failures: TransferQueueItem[];
2568
2701
  }
2569
- /** Minimal transfer queue with concurrency, pause/resume, cancellation, and drain summaries. */
2702
+ /**
2703
+ * Minimal transfer queue with concurrency, pause/resume, cancellation, and drain summaries.
2704
+ *
2705
+ * Wrap a {@link TransferEngine} with a queue when you need to run many transfers
2706
+ * concurrently with bounded parallelism, observe per-job progress, or drive
2707
+ * a UI from a single source of truth. Items are FIFO; failures and successes
2708
+ * are surfaced via observers and in the final {@link TransferQueueSummary}.
2709
+ *
2710
+ * @example Run a batch of uploads with concurrency=4
2711
+ * ```ts
2712
+ * import {
2713
+ * TransferQueue,
2714
+ * createProviderTransferExecutor,
2715
+ * } from "@zero-transfer/sdk";
2716
+ *
2717
+ * const queue = new TransferQueue({
2718
+ * concurrency: 4,
2719
+ * executor: createProviderTransferExecutor({ client }),
2720
+ * onProgress: (e) => console.log(`${e.jobId}: ${e.bytesTransferred}`),
2721
+ * onError: (item, err) => console.error(`${item.job.id} failed`, err),
2722
+ * });
2723
+ *
2724
+ * for (const file of files) {
2725
+ * queue.enqueue({
2726
+ * id: file.name,
2727
+ * operation: "upload",
2728
+ * source: { profile: localProfile, path: file.path },
2729
+ * destination: { profile: s3Profile, path: `/lake/${file.name}` },
2730
+ * });
2731
+ * }
2732
+ *
2733
+ * const summary = await queue.drain();
2734
+ * console.log(`Completed ${summary.completed} / ${summary.total}`);
2735
+ * ```
2736
+ */
2570
2737
  declare class TransferQueue {
2571
2738
  private readonly engine;
2572
2739
  private readonly items;
@@ -2846,6 +3013,26 @@ interface DiffRemoteTreesOptions {
2846
3013
  * @param destinationPath - Destination-side root path being compared.
2847
3014
  * @param options - Optional comparison controls.
2848
3015
  * @returns Diff result containing entries and a summary.
3016
+ *
3017
+ * @example Diff two SFTP subtrees and feed the result into createSyncPlan
3018
+ * ```ts
3019
+ * import { createSyncPlan, diffRemoteTrees } from "@zero-transfer/sdk";
3020
+ *
3021
+ * const diff = await diffRemoteTrees(
3022
+ * srcSession.fs, "/exports",
3023
+ * dstSession.fs, "/exports",
3024
+ * { compareUniqueId: true },
3025
+ * );
3026
+ *
3027
+ * console.log(diff.summary); // { added, removed, changed, unchanged }
3028
+ *
3029
+ * const plan = createSyncPlan({
3030
+ * id: "exports-sync",
3031
+ * diff,
3032
+ * source: { provider: "sftp", rootPath: "/exports" },
3033
+ * destination: { provider: "sftp", rootPath: "/exports" },
3034
+ * });
3035
+ * ```
2849
3036
  */
2850
3037
  declare function diffRemoteTrees(source: RemoteFileSystem, sourcePath: string, destination: RemoteFileSystem, destinationPath: string, options?: DiffRemoteTreesOptions): Promise<RemoteTreeDiff>;
2851
3038
 
@@ -2917,6 +3104,31 @@ interface CreateSyncPlanOptions {
2917
3104
  * @param options - Inputs and policies that shape the plan.
2918
3105
  * @returns Transfer plan ready for `createTransferJobsFromPlan` or queue execution.
2919
3106
  * @throws {@link ConfigurationError} When `conflictPolicy: "error"` encounters a conflict.
3107
+ *
3108
+ * @example Mirror SFTP → S3 with deletes
3109
+ * ```ts
3110
+ * import {
3111
+ * createSyncPlan,
3112
+ * diffRemoteTrees,
3113
+ * summarizeTransferPlan,
3114
+ * } from "@zero-transfer/sdk";
3115
+ *
3116
+ * const diff = await diffRemoteTrees(
3117
+ * srcSession.fs, "/dist",
3118
+ * dstSession.fs, "/releases/current",
3119
+ * );
3120
+ *
3121
+ * const plan = createSyncPlan({
3122
+ * id: "release-mirror",
3123
+ * diff,
3124
+ * source: { provider: "sftp", rootPath: "/dist" },
3125
+ * destination: { provider: "s3", rootPath: "/releases/current" },
3126
+ * deletePolicy: "mirror",
3127
+ * conflictPolicy: "overwrite",
3128
+ * });
3129
+ *
3130
+ * console.table(summarizeTransferPlan(plan));
3131
+ * ```
2920
3132
  */
2921
3133
  declare function createSyncPlan(options: CreateSyncPlanOptions): TransferPlan;
2922
3134
 
@@ -3032,9 +3244,39 @@ interface CreateAtomicDeployPlanOptions {
3032
3244
  /**
3033
3245
  * Builds an {@link AtomicDeployPlan} that stages a release, swaps it live, and prunes old releases.
3034
3246
  *
3247
+ * The plan describes a blue/green-style deploy:
3248
+ * 1. Upload to a timestamped staging directory under `<destination>/.releases/`.
3249
+ * 2. Atomically swap the `current` symlink/rename to point at the new release.
3250
+ * 3. Optionally prune old releases beyond `retain`.
3251
+ *
3252
+ * No I/O is performed — the host executes the plan steps. Pair with
3253
+ * {@link createTransferPlan} or {@link createTransferJobsFromPlan} to execute.
3254
+ *
3035
3255
  * @param options - Inputs and policies that shape the deploy.
3036
3256
  * @returns Structured deploy plan ready for execution by the calling host.
3037
3257
  * @throws {@link ConfigurationError} When `retain` is less than `1` or the destination root is empty.
3258
+ *
3259
+ * @example Plan a release with rollback path
3260
+ * ```ts
3261
+ * import { createAtomicDeployPlan } from "@zero-transfer/sdk";
3262
+ *
3263
+ * const plan = createAtomicDeployPlan({
3264
+ * id: "web-2026-04-28",
3265
+ * source: { rootPath: "./dist" },
3266
+ * destination: {
3267
+ * profile: { host: "web1.example.com", provider: "sftp", username: "deploy" },
3268
+ * rootPath: "/srv/www",
3269
+ * },
3270
+ * retain: 5,
3271
+ * existingReleases: [
3272
+ * "/srv/www/.releases/2026-04-21T00-00-00Z",
3273
+ * "/srv/www/.releases/2026-04-14T00-00-00Z",
3274
+ * ],
3275
+ * });
3276
+ *
3277
+ * console.log(plan.swap); // staging → current rename
3278
+ * console.log(plan.prune); // releases scheduled for removal
3279
+ * ```
3038
3280
  */
3039
3281
  declare function createAtomicDeployPlan(options: CreateAtomicDeployPlanOptions): AtomicDeployPlan;
3040
3282