@ai-matrx/kit 0.12.1 → 0.13.1

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.js CHANGED
@@ -804,7 +804,7 @@ function messageText(message, data) {
804
804
  }
805
805
  function createMatrxToast({
806
806
  toast: hostToast,
807
- capture
807
+ capture: capture2
808
808
  }) {
809
809
  if (typeof hostToast !== "function") {
810
810
  throw new Error(
@@ -812,9 +812,9 @@ function createMatrxToast({
812
812
  );
813
813
  }
814
814
  function captureToast(kind, message, data) {
815
- if (!capture) return;
815
+ if (!capture2) return;
816
816
  try {
817
- capture({
817
+ capture2({
818
818
  source: "user-toast",
819
819
  message: `${kind === "warning" ? "[warning] " : ""}${messageText(message, data)}`,
820
820
  userMessage: messageText(message, data),
@@ -2719,7 +2719,1152 @@ async function decodeQrFromImageFile(file) {
2719
2719
  bitmap.close();
2720
2720
  }
2721
2721
  }
2722
+
2723
+ // src/html-escape.ts
2724
+ var HTML_ESCAPES = {
2725
+ "&": "&",
2726
+ "<": "&lt;",
2727
+ ">": "&gt;",
2728
+ '"': "&quot;",
2729
+ "'": "&#39;"
2730
+ };
2731
+ var HTML_ESCAPE_RE = /[&<>"']/g;
2732
+ function escapeHtml(value) {
2733
+ if (typeof value !== "string") return "";
2734
+ return value.replace(HTML_ESCAPE_RE, (char) => HTML_ESCAPES[char] ?? char);
2735
+ }
2736
+
2737
+ // src/content-transfer/agent-payload.ts
2738
+ var escapeXml = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
2739
+ var xmlName = (name) => {
2740
+ if (!/^[A-Za-z_][A-Za-z0-9_.-]*$/.test(name)) throw new Error(`Invalid AI envelope name: ${name}`);
2741
+ return name;
2742
+ };
2743
+ var presentEntries = (values) => Object.entries(values ?? {}).filter(([, value]) => value !== null && value !== void 0 && value !== "");
2744
+ function fenceJsonBlock(json) {
2745
+ const runs = json.match(/`+/g) ?? [];
2746
+ const fence = "`".repeat(Math.max(3, ...runs.map((run) => run.length + 1)));
2747
+ return `${fence}json
2748
+ ${json.trimEnd()}
2749
+ ${fence}`;
2750
+ }
2751
+ function buildAgentPayload(input, environment = {}) {
2752
+ const kind = xmlName(input.kind);
2753
+ const url = environment.url ?? (typeof window === "undefined" ? "" : window.location.href);
2754
+ const route = environment.route ?? (typeof window === "undefined" ? "" : window.location.pathname);
2755
+ const attrs = presentEntries(input.attributes).map(([key, value]) => ` ${xmlName(key)}="${escapeXml(String(value))}"`).join("");
2756
+ const entries = [
2757
+ ["location", input.location],
2758
+ ...url ? [["url", url]] : [],
2759
+ ...route ? [["route", route]] : [],
2760
+ ["copied", input.description],
2761
+ ["copied-at", environment.capturedAt ?? (/* @__PURE__ */ new Date()).toISOString()],
2762
+ ...presentEntries(input.context).map(([key, value]) => [xmlName(key), String(value)])
2763
+ ];
2764
+ const json = JSON.stringify(input.data, null, 2);
2765
+ if (json === void 0) throw new Error("AI envelope data must be JSON serializable.");
2766
+ const safeJson = json.replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/&/g, "\\u0026");
2767
+ const context = entries.map(([key, value]) => `<${key}>${escapeXml(value)}</${key}>`).join("\n");
2768
+ const summary = input.summary ? `<summary>
2769
+ ${escapeXml(input.summary)}
2770
+ </summary>
2771
+ ` : "";
2772
+ return `<${kind}${attrs}>
2773
+ <context>
2774
+ ${context}
2775
+ </context>
2776
+ ${summary}<data format="json">
2777
+ ${fenceJsonBlock(safeJson)}
2778
+ </data>
2779
+ </${kind}>`;
2780
+ }
2781
+
2782
+ // src/content-transfer.ts
2783
+ var ContentTransferError = class extends Error {
2784
+ code;
2785
+ path;
2786
+ constructor(code, message, path) {
2787
+ super(message);
2788
+ this.code = code;
2789
+ this.path = path;
2790
+ }
2791
+ };
2792
+ var bound = /* @__PURE__ */ Symbol("bound-all-matching");
2793
+ var stop = (s) => {
2794
+ if (s.aborted) throw new DOMException("Cancelled", "AbortError");
2795
+ };
2796
+ var enc = (x) => x.replace(/~/g, "~0").replace(/\//g, "~1");
2797
+ var dec = (x) => x.replace(/~1/g, "/").replace(/~0/g, "~");
2798
+ function clone(v, path = "", seen = /* @__PURE__ */ new WeakSet()) {
2799
+ if (v === null || typeof v === "string" || typeof v === "boolean") return v;
2800
+ if (typeof v === "number") {
2801
+ if (!Number.isFinite(v))
2802
+ throw new ContentTransferError(
2803
+ "unsupported-value",
2804
+ "Only finite numbers are transferable",
2805
+ path
2806
+ );
2807
+ return v;
2808
+ }
2809
+ if (typeof v !== "object")
2810
+ throw new ContentTransferError(
2811
+ "unsupported-value",
2812
+ "Unsupported value",
2813
+ path
2814
+ );
2815
+ if (seen.has(v))
2816
+ throw new ContentTransferError(
2817
+ "circular-value",
2818
+ "Circular values cannot be transferred",
2819
+ path
2820
+ );
2821
+ if (!Array.isArray(v) && Object.getPrototypeOf(v) !== Object.prototype && Object.getPrototypeOf(v) !== null)
2822
+ throw new ContentTransferError(
2823
+ "unsupported-value",
2824
+ "Only plain JSON objects are transferable",
2825
+ path
2826
+ );
2827
+ seen.add(v);
2828
+ if (Array.isArray(v)) {
2829
+ for (let index = 0; index < v.length; index += 1)
2830
+ if (!Object.hasOwn(v, index))
2831
+ throw new ContentTransferError(
2832
+ "unsupported-value",
2833
+ "Sparse arrays cannot be transferred",
2834
+ `${path}/${index}`
2835
+ );
2836
+ }
2837
+ const out = Array.isArray(v) ? v.map((x, i) => clone(x, `${path}/${i}`, seen)) : Object.fromEntries(
2838
+ Object.entries(v).map(([k, x]) => [
2839
+ k,
2840
+ clone(x, `${path}/${enc(k)}`, seen)
2841
+ ])
2842
+ );
2843
+ seen.delete(v);
2844
+ return out;
2845
+ }
2846
+ function normalizeTransferJson(value) {
2847
+ return clone(value);
2848
+ }
2849
+ function deepFreeze(v) {
2850
+ if (ArrayBuffer.isView(v)) return v;
2851
+ if (v && typeof v === "object" && !Object.isFrozen(v)) {
2852
+ Object.freeze(v);
2853
+ for (const x of Object.values(v)) deepFreeze(x);
2854
+ }
2855
+ return v;
2856
+ }
2857
+ function at(v, path) {
2858
+ validatePointer(path);
2859
+ if (path === "") return v;
2860
+ if (!path.startsWith("/"))
2861
+ throw new ContentTransferError(
2862
+ "invalid-path",
2863
+ "Expected RFC 6901 pointer",
2864
+ path
2865
+ );
2866
+ let cur = v;
2867
+ for (const part of path.slice(1).split("/").map(dec)) {
2868
+ if (Array.isArray(cur)) cur = cur[Number(part)];
2869
+ else if (cur && typeof cur === "object")
2870
+ cur = Object.hasOwn(cur, part) ? cur[part] : void 0;
2871
+ else return void 0;
2872
+ }
2873
+ return cur;
2874
+ }
2875
+ function validatePointer(path) {
2876
+ if (path !== "" && !path.startsWith("/") || /~(?![01])/u.test(path))
2877
+ throw new ContentTransferError(
2878
+ "invalid-path",
2879
+ "Expected an RFC 6901 JSON pointer",
2880
+ path
2881
+ );
2882
+ }
2883
+ function readTransferCell(row, column) {
2884
+ return at(row, column.path);
2885
+ }
2886
+ function without(v, paths, omit, path = "") {
2887
+ if (paths.includes(path)) {
2888
+ omit.push({ path, reason: "excluded" });
2889
+ return void 0;
2890
+ }
2891
+ if (Array.isArray(v))
2892
+ return v.map((x, i) => without(x, paths, omit, `${path}/${i}`)).filter((x) => x !== void 0);
2893
+ if (v && typeof v === "object") {
2894
+ const out = /* @__PURE__ */ Object.create(null);
2895
+ for (const [k, x] of Object.entries(v)) {
2896
+ const y = without(x, paths, omit, `${path}/${enc(k)}`);
2897
+ if (y !== void 0) out[k] = y;
2898
+ }
2899
+ return out;
2900
+ }
2901
+ return v;
2902
+ }
2903
+ function projectValue(v, rules, target, omit) {
2904
+ rules.forEach((rule) => validatePointer(rule.path));
2905
+ return without(
2906
+ clone(v),
2907
+ rules.filter(
2908
+ (r) => r.target === target && (!r.exportable || r.classification !== "ordinary")
2909
+ ).map((r) => r.path),
2910
+ omit
2911
+ ) ?? null;
2912
+ }
2913
+ function normalize(p, projection, omit) {
2914
+ if (p.kind === "text" || p.kind === "markdown") {
2915
+ if (typeof p.text !== "string")
2916
+ throw new ContentTransferError(
2917
+ "unsupported-value",
2918
+ "Text payload must contain a string",
2919
+ "/text"
2920
+ );
2921
+ const value = projectValue(p.text, projection.rules, "payload", omit);
2922
+ return { kind: p.kind, text: typeof value === "string" ? value : "" };
2923
+ }
2924
+ if (p.kind === "json")
2925
+ return {
2926
+ kind: "json",
2927
+ value: projectValue(p.value, projection.rules, "payload", omit)
2928
+ };
2929
+ if (p.kind === "registered")
2930
+ return {
2931
+ kind: "registered",
2932
+ format: p.format,
2933
+ value: projectValue(p.value, projection.rules, "payload", omit)
2934
+ };
2935
+ const rowsPayload = p;
2936
+ if (p.kind !== "rows")
2937
+ throw new ContentTransferError(
2938
+ "invalid-payload",
2939
+ "Unsupported payload kind"
2940
+ );
2941
+ const columns = rowsPayload.columns.map((c) => ({ ...c }));
2942
+ resolveTransferRegistry(columns);
2943
+ columns.forEach((column) => validatePointer(column.path));
2944
+ const rules = [
2945
+ ...projection.rules,
2946
+ ...columns.filter(
2947
+ (c) => c.exportable === false || c.classification === "secret" || c.classification === "credential"
2948
+ ).map((c) => ({
2949
+ target: "row",
2950
+ path: c.path,
2951
+ exportable: c.exportable ?? true,
2952
+ classification: c.classification ?? "ordinary"
2953
+ }))
2954
+ ];
2955
+ return {
2956
+ kind: "rows",
2957
+ columns,
2958
+ rows: rowsPayload.rows.map((row, index) => {
2959
+ if (!row || typeof row !== "object" || Array.isArray(row))
2960
+ throw new ContentTransferError(
2961
+ "invalid-row",
2962
+ "A table row must be a JSON object",
2963
+ `/rows/${index}`
2964
+ );
2965
+ const projected = projectValue(row, rules, "row", omit);
2966
+ return projected === null ? {} : projected;
2967
+ })
2968
+ };
2969
+ }
2970
+ function projectSnapshot(raw, projection) {
2971
+ const omissions = raw.omissions.map((o) => ({ ...o }));
2972
+ const normalized = normalize(raw.payload, projection, omissions);
2973
+ const payload = raw.limits ? limitPayload(normalized, raw.limits, omissions) : normalized;
2974
+ const included = payload.kind === "rows" ? payload.rows.length : raw.coverage.included;
2975
+ return deepFreeze({
2976
+ ...raw,
2977
+ payload,
2978
+ coverage: {
2979
+ ...raw.coverage,
2980
+ included,
2981
+ ...included < raw.coverage.included ? { status: "partial", reason: "Source export limit applied" } : {}
2982
+ },
2983
+ omissions,
2984
+ sections: raw.sections.filter(
2985
+ (section) => !projection.rules.some(
2986
+ (rule) => rule.target === "payload" && (!rule.exportable || rule.classification !== "ordinary") && (section.path === rule.path || section.path.startsWith(`${rule.path}/`))
2987
+ )
2988
+ ).map((x) => ({ ...x })),
2989
+ ...raw.limits ? { limits: { ...raw.limits } } : {}
2990
+ });
2991
+ }
2992
+ var uid = () => globalThis.crypto?.randomUUID?.() ?? `capture-${Date.now()}-${Math.random()}`;
2993
+ function directSource(payload, options = {}) {
2994
+ const id = options.id ?? uid();
2995
+ return {
2996
+ projection: options.projection ?? { rules: [] },
2997
+ snapshot: {
2998
+ id,
2999
+ sourceId: options.sourceId ?? id,
3000
+ revision: options.revision ?? uid(),
3001
+ capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
3002
+ label: options.label ?? "Content",
3003
+ payload,
3004
+ coverage: options.coverage ?? {
3005
+ status: "complete",
3006
+ included: payload.kind === "rows" ? payload.rows.length : 1,
3007
+ total: payload.kind === "rows" ? payload.rows.length : 1
3008
+ },
3009
+ unsavedChanges: options.unsavedChanges ?? false,
3010
+ omissions: [],
3011
+ sections: options.sections ?? [],
3012
+ ...options.limits ? { limits: { ...options.limits } } : {}
3013
+ }
3014
+ };
3015
+ }
3016
+ async function capture(source, signal, scope = "target") {
3017
+ stop(signal);
3018
+ const captured = "kind" in source ? directSource(source) : await source.capture({ scope, signal });
3019
+ stop(signal);
3020
+ const all = captured.allMatching;
3021
+ if (all && (all.query.sourceId !== captured.snapshot.sourceId || all.query.revision !== captured.snapshot.revision || all.query.order.length === 0))
3022
+ throw new ContentTransferError(
3023
+ "query-mismatch",
3024
+ "All-matching query must be captured with stable ordering"
3025
+ );
3026
+ const snapshot = projectSnapshot(captured.snapshot, captured.projection);
3027
+ if (!all) return { snapshot };
3028
+ return {
3029
+ snapshot,
3030
+ allMatching: deepFreeze({
3031
+ [bound]: true,
3032
+ source: {
3033
+ ...all,
3034
+ query: {
3035
+ ...all.query,
3036
+ query: clone(all.query.query),
3037
+ order: all.query.order.map((x) => ({ ...x }))
3038
+ }
3039
+ },
3040
+ projection: { rules: captured.projection.rules.map((x) => ({ ...x })) },
3041
+ columns: snapshot.payload.kind === "rows" ? snapshot.payload.columns : [],
3042
+ ...snapshot.limits ? { limits: { ...snapshot.limits } } : {}
3043
+ })
3044
+ };
3045
+ }
3046
+ function createDraft(s) {
3047
+ return deepFreeze({
3048
+ snapshotId: s.id,
3049
+ sourceId: s.sourceId,
3050
+ sourceRevision: s.revision,
3051
+ revision: 0,
3052
+ payload: normalize(s.payload, { rules: [] }, []),
3053
+ omissions: [...s.omissions],
3054
+ manuallyEdited: false,
3055
+ provenance: [{ kind: "original", description: "Captured source snapshot" }]
3056
+ });
3057
+ }
3058
+ function revise(d, p, o, description, manual = d.manuallyEdited, kind = "deterministic", baseOmissions = d.omissions) {
3059
+ const { history: _history, ...previous } = d;
3060
+ return deepFreeze({
3061
+ ...d,
3062
+ revision: d.revision + 1,
3063
+ payload: normalize(p, { rules: [] }, []),
3064
+ omissions: [...baseOmissions, ...o],
3065
+ manuallyEdited: manual,
3066
+ provenance: [...d.provenance, { kind, description }],
3067
+ history: [...d.history ?? [], previous]
3068
+ });
3069
+ }
3070
+ var editDraft = (d, p) => revise(d, p, [], "Manual edit", true, "manual");
3071
+ var resetDraft = (s) => createDraft(s);
3072
+ var sourceChanged = (d, s) => d.sourceId !== s.sourceId || d.sourceRevision !== s.revision;
3073
+ function undoDraft(d) {
3074
+ const previous = d.history?.at(-1);
3075
+ if (!previous) return d;
3076
+ return deepFreeze({
3077
+ ...previous,
3078
+ revision: d.revision + 1,
3079
+ history: d.history.slice(0, -1)
3080
+ });
3081
+ }
3082
+ function refreshDraft(draft, snapshot, choice) {
3083
+ return choice === "keep" ? draft : createDraft(snapshot);
3084
+ }
3085
+ function applySectionSelection(d, s, ids) {
3086
+ if (d.snapshotId !== s.id || d.sourceId !== s.sourceId || d.sourceRevision !== s.revision)
3087
+ throw new ContentTransferError(
3088
+ "snapshot-mismatch",
3089
+ "Section selection requires the draft's captured source snapshot"
3090
+ );
3091
+ const selected = new Set(ids), omit = [], paths = s.sections.filter((x) => !selected.has(x.id)).map((x) => {
3092
+ omit.push({ path: x.path, reason: "excluded" });
3093
+ return x.path;
3094
+ }), baseOmissions = s.omissions;
3095
+ if (s.payload.kind === "json")
3096
+ return revise(
3097
+ d,
3098
+ { kind: "json", value: without(s.payload.value, paths, []) ?? null },
3099
+ omit,
3100
+ "Selected sections",
3101
+ d.manuallyEdited,
3102
+ "deterministic",
3103
+ baseOmissions
3104
+ );
3105
+ if (s.payload.kind === "registered")
3106
+ return revise(
3107
+ d,
3108
+ {
3109
+ kind: "registered",
3110
+ format: s.payload.format,
3111
+ value: without(s.payload.value, paths, []) ?? null
3112
+ },
3113
+ omit,
3114
+ "Selected sections",
3115
+ d.manuallyEdited,
3116
+ "deterministic",
3117
+ baseOmissions
3118
+ );
3119
+ return revise(
3120
+ d,
3121
+ s.payload,
3122
+ omit,
3123
+ "Selected sections",
3124
+ d.manuallyEdited,
3125
+ "deterministic",
3126
+ baseOmissions
3127
+ );
3128
+ }
3129
+ function transformRows(d, o) {
3130
+ if (d.payload.kind !== "rows") return d;
3131
+ if (o.top != null) assertLimit(o.top, "maxRows");
3132
+ const cols = o.visibleColumns ? o.visibleColumns.map(
3133
+ (id) => d.payload.kind === "rows" ? d.payload.columns.find((c) => c.id === id) : void 0
3134
+ ).filter((c) => Boolean(c)) : d.payload.columns.filter((c) => c.visible);
3135
+ const get = readTransferCell;
3136
+ let rows = [...d.payload.rows], omit = [];
3137
+ const before = rows.length;
3138
+ if (o.selectedIndices !== void 0) {
3139
+ const selected = /* @__PURE__ */ new Set();
3140
+ for (const index of o.selectedIndices) {
3141
+ if (!Number.isSafeInteger(index) || index < 0 || index >= d.payload.rows.length)
3142
+ throw new ContentTransferError(
3143
+ "invalid-selection-index",
3144
+ "Selected row indexes must be non-negative positions in the input draft rows"
3145
+ );
3146
+ selected.add(index);
3147
+ }
3148
+ rows = d.payload.rows.filter((_, index) => selected.has(index));
3149
+ }
3150
+ if (o.selectedIds && o.idColumn) {
3151
+ const set = new Set(o.selectedIds);
3152
+ const idColumn = d.payload.columns.find((c) => c.id === o.idColumn);
3153
+ rows = rows.filter(
3154
+ (r) => set.has(String(idColumn ? get(r, idColumn) : r[o.idColumn]))
3155
+ );
3156
+ }
3157
+ if (o.search) {
3158
+ const q = o.search.toLowerCase();
3159
+ rows = rows.filter(
3160
+ (r) => cols.some(
3161
+ (c) => String(get(r, c) ?? "").toLowerCase().includes(q)
3162
+ )
3163
+ );
3164
+ }
3165
+ for (const [id, q] of Object.entries(o.filters ?? {})) {
3166
+ const c = cols.find((x) => x.id === id);
3167
+ if (c)
3168
+ rows = rows.filter(
3169
+ (r) => String(get(r, c) ?? "").toLowerCase().includes(q.toLowerCase())
3170
+ );
3171
+ }
3172
+ if (rows.length !== before)
3173
+ omit.push({
3174
+ path: "/rows",
3175
+ reason: "filtered",
3176
+ count: before - rows.length
3177
+ });
3178
+ if (o.sort) {
3179
+ const c = cols.find((x) => x.id === o.sort.column);
3180
+ if (c)
3181
+ rows.sort((a, b) => {
3182
+ const left = get(a, c);
3183
+ const right = get(b, c);
3184
+ const compare = typeof left === "number" && typeof right === "number" ? left - right : String(left ?? "").localeCompare(String(right ?? ""));
3185
+ return compare * (o.sort.direction === "asc" ? 1 : -1);
3186
+ });
3187
+ }
3188
+ if (o.top != null && rows.length > o.top) {
3189
+ omit.push({
3190
+ path: "/rows",
3191
+ reason: "truncated",
3192
+ count: rows.length - o.top
3193
+ });
3194
+ rows = rows.slice(0, o.top);
3195
+ }
3196
+ if (o.structuredProjection === "visible") {
3197
+ rows = rows.map(
3198
+ (r) => Object.fromEntries(cols.map((c) => [c.id, get(r, c) ?? null]))
3199
+ );
3200
+ omit.push({
3201
+ path: "/columns",
3202
+ reason: "excluded",
3203
+ count: d.payload.columns.length - cols.length
3204
+ });
3205
+ }
3206
+ return revise(
3207
+ d,
3208
+ {
3209
+ kind: "rows",
3210
+ rows,
3211
+ columns: cols.map((c) => ({
3212
+ ...c,
3213
+ visible: true,
3214
+ ...o.structuredProjection === "visible" ? { path: `/${enc(c.id)}` } : {}
3215
+ }))
3216
+ },
3217
+ omit,
3218
+ "Prepared row subset"
3219
+ );
3220
+ }
3221
+ function reduceJson(draft, options) {
3222
+ if (draft.payload.kind !== "json" && draft.payload.kind !== "registered")
3223
+ return draft;
3224
+ const omissions = [];
3225
+ options.exclude?.forEach(validatePointer);
3226
+ const filtered = without(clone(draft.payload.value), options.exclude ?? [], omissions) ?? null;
3227
+ const payload = limitPayload(
3228
+ { ...draft.payload, value: filtered },
3229
+ options,
3230
+ omissions
3231
+ );
3232
+ return revise(draft, payload, omissions, "Reduced JSON");
3233
+ }
3234
+ async function collectAllMatching(c, signal) {
3235
+ const rows = [], omissions = [], ids = /* @__PURE__ */ new Set(), cursors = /* @__PURE__ */ new Set();
3236
+ let cursor = null, token, last = {
3237
+ status: "unknown",
3238
+ included: 0,
3239
+ total: null
3240
+ };
3241
+ let certifiedTotal;
3242
+ const maxRows = c.limits?.maxRows;
3243
+ if (maxRows != null) assertLimit(maxRows, "maxRows");
3244
+ const finishAtLimit = (total, knownOmitted) => ({
3245
+ rows: deepFreeze(rows),
3246
+ omissions: deepFreeze([
3247
+ ...omissions,
3248
+ {
3249
+ path: "/rows",
3250
+ reason: "truncated",
3251
+ ...knownOmitted === void 0 || knownOmitted <= 0 ? {} : { count: knownOmitted }
3252
+ }
3253
+ ]),
3254
+ coverage: deepFreeze({
3255
+ status: "partial",
3256
+ included: rows.length,
3257
+ total,
3258
+ reason: "Source export limit applied"
3259
+ })
3260
+ });
3261
+ try {
3262
+ if (maxRows === 0) return finishAtLimit(null);
3263
+ do {
3264
+ stop(signal);
3265
+ const page = await c.source.page({
3266
+ query: c.source.query,
3267
+ cursor,
3268
+ consistencyToken: token ?? null,
3269
+ signal
3270
+ });
3271
+ stop(signal);
3272
+ if (token === void 0) token = page.consistencyToken;
3273
+ else if (page.consistencyToken !== token)
3274
+ throw new ContentTransferError(
3275
+ "consistency-token-changed",
3276
+ "All-matching export changed during collection"
3277
+ );
3278
+ if (page.coverage.included !== page.rows.length)
3279
+ throw new ContentTransferError(
3280
+ "invalid-page-coverage",
3281
+ "Page count does not match returned rows"
3282
+ );
3283
+ if (page.coverage.total !== null && (!Number.isSafeInteger(page.coverage.total) || page.coverage.total < 0))
3284
+ throw new ContentTransferError(
3285
+ "invalid-page-coverage",
3286
+ "Page total must be a non-negative integer or null"
3287
+ );
3288
+ if (certifiedTotal === void 0) certifiedTotal = page.coverage.total;
3289
+ else if (page.coverage.total !== certifiedTotal)
3290
+ throw new ContentTransferError(
3291
+ "inconsistent-total",
3292
+ "All-matching source changed its reported total during collection"
3293
+ );
3294
+ const projected = normalize(
3295
+ { kind: "rows", rows: page.rows, columns: [...c.columns] },
3296
+ c.projection,
3297
+ omissions
3298
+ ).rows;
3299
+ let uniqueBeyondLimit = 0;
3300
+ for (const row of projected) {
3301
+ const id = c.source.getRowId(row);
3302
+ if (!id)
3303
+ throw new ContentTransferError(
3304
+ "invalid-row-id",
3305
+ "All-matching source returned empty projected ID"
3306
+ );
3307
+ if (!ids.has(id)) {
3308
+ ids.add(id);
3309
+ if (maxRows == null || rows.length < maxRows)
3310
+ rows.push(
3311
+ limitPayload(
3312
+ { kind: "rows", rows: [row], columns: [...c.columns] },
3313
+ { ...c.limits, maxRows: null },
3314
+ omissions
3315
+ ).rows[0]
3316
+ );
3317
+ else uniqueBeyondLimit += 1;
3318
+ } else omissions.push({ path: `/rows/${enc(id)}`, reason: "duplicate" });
3319
+ }
3320
+ if (page.coverage.total !== null && page.coverage.total < ids.size)
3321
+ throw new ContentTransferError(
3322
+ "invalid-page-coverage",
3323
+ "Page total is smaller than the accumulated unique row count"
3324
+ );
3325
+ last = page.coverage;
3326
+ if (maxRows != null && rows.length >= maxRows && (uniqueBeyondLimit > 0 || page.nextCursor !== null))
3327
+ return finishAtLimit(
3328
+ page.coverage.total,
3329
+ page.nextCursor === null ? uniqueBeyondLimit : page.coverage.total != null && page.coverage.total > rows.length ? page.coverage.total - rows.length : void 0
3330
+ );
3331
+ cursor = page.nextCursor;
3332
+ if (cursor !== null && (!cursor || cursors.has(cursor)))
3333
+ throw new ContentTransferError(
3334
+ "non-advancing-cursor",
3335
+ "All-matching source repeated a cursor"
3336
+ );
3337
+ if (cursor) cursors.add(cursor);
3338
+ } while (cursor !== null);
3339
+ const complete = c.source.stableSnapshot === true && last.status === "complete" && last.total === rows.length && token !== void 0;
3340
+ return {
3341
+ rows: deepFreeze(rows),
3342
+ omissions: deepFreeze(omissions),
3343
+ coverage: deepFreeze(
3344
+ complete ? { ...last, included: rows.length } : {
3345
+ ...last,
3346
+ status: "partial",
3347
+ included: rows.length,
3348
+ reason: last.reason ?? "Source did not certify a stable complete snapshot"
3349
+ }
3350
+ )
3351
+ };
3352
+ } catch (e) {
3353
+ const error = e instanceof ContentTransferError ? e : new ContentTransferError(
3354
+ signal.aborted ? "cancelled" : "page-failed",
3355
+ e instanceof Error ? e.message : "Page collection failed"
3356
+ );
3357
+ return {
3358
+ rows: deepFreeze(rows),
3359
+ omissions: deepFreeze(omissions),
3360
+ coverage: deepFreeze({
3361
+ status: "partial",
3362
+ included: rows.length,
3363
+ total: last.total,
3364
+ reason: error.message
3365
+ }),
3366
+ error
3367
+ };
3368
+ }
3369
+ }
3370
+ var textValue = (value) => value === void 0 ? "" : typeof value === "string" ? value : stringifyJson(value, { style: "compact" });
3371
+ function sealTransferArtifact(artifact) {
3372
+ if (!artifact.file)
3373
+ return deepFreeze({
3374
+ ...artifact,
3375
+ omissions: artifact.omissions.map((o) => ({ ...o }))
3376
+ });
3377
+ const bytes = artifact.file.bytes.slice();
3378
+ const file = {
3379
+ filename: artifact.file.filename,
3380
+ mime: artifact.file.mime,
3381
+ get bytes() {
3382
+ return bytes.slice();
3383
+ }
3384
+ };
3385
+ return deepFreeze({
3386
+ ...artifact,
3387
+ file,
3388
+ omissions: artifact.omissions.map((o) => ({ ...o }))
3389
+ });
3390
+ }
3391
+ function serialize(draft, format, options = {}) {
3392
+ const payload = draft.payload;
3393
+ const omissions = draft.omissions.map((o) => ({ ...o }));
3394
+ let plainText = "", html;
3395
+ let mime = "text/plain;charset=utf-8", extension = "txt";
3396
+ const columnCell = (row, column) => textValue(readTransferCell(row, column));
3397
+ if ((format === "csv" || format === "tsv") && payload.kind !== "rows") {
3398
+ throw new ContentTransferError(
3399
+ "unsupported-format",
3400
+ `${format.toUpperCase()} requires tabular data`
3401
+ );
3402
+ }
3403
+ if (format === "json" || format === "compact-json") {
3404
+ const value = payload.kind === "rows" ? payload.rows : payload.kind === "text" || payload.kind === "markdown" ? payload.text : payload.value;
3405
+ plainText = stringifyJson(value, {
3406
+ style: format === "json" ? "pretty" : "compact"
3407
+ });
3408
+ mime = "application/json;charset=utf-8";
3409
+ extension = "json";
3410
+ } else if (payload.kind === "rows") {
3411
+ const columns = payload.columns.filter(
3412
+ (c) => c.visible && c.exportable !== false && c.classification !== "secret" && c.classification !== "credential"
3413
+ );
3414
+ if (format === "markdown") {
3415
+ const escapeCell = (value) => escapeHtml(value).replace(/\\/g, "\\\\").replace(/\|/g, "\\|").replace(/\r\n|\r|\n/g, "<br>");
3416
+ plainText = [
3417
+ `| ${columns.map((c) => escapeCell(c.label)).join(" | ")} |`,
3418
+ `| ${columns.map(() => "---").join(" | ")} |`,
3419
+ ...payload.rows.map(
3420
+ (row) => `| ${columns.map((c) => escapeCell(columnCell(row, c))).join(" | ")} |`
3421
+ )
3422
+ ].join("\n");
3423
+ mime = "text/markdown;charset=utf-8";
3424
+ extension = "md";
3425
+ } else {
3426
+ const delimiter = format === "csv" ? "," : " ";
3427
+ const safe = options.spreadsheetSafe ?? format === "tsv";
3428
+ const encode = (value, path, isString = true) => {
3429
+ let text = value;
3430
+ if (safe && isString && /^[\t\r\n ]*[=+\-@]/.test(text)) {
3431
+ text = `'${text}`;
3432
+ omissions.push({ path, reason: "escaped", count: 1 });
3433
+ }
3434
+ return text.includes(delimiter) || /["\n\r]/.test(text) ? `"${text.replace(/"/g, '""')}"` : text;
3435
+ };
3436
+ plainText = [
3437
+ columns.map((c) => encode(c.label, `/columns/${enc(c.id)}`)).join(delimiter),
3438
+ ...payload.rows.map(
3439
+ (row, index) => columns.map(
3440
+ (c) => encode(
3441
+ columnCell(row, c),
3442
+ `/rows/${index}${c.path}`,
3443
+ typeof readTransferCell(row, c) === "string"
3444
+ )
3445
+ ).join(delimiter)
3446
+ )
3447
+ ].join("\n");
3448
+ if (format === "csv") {
3449
+ mime = "text/csv;charset=utf-8";
3450
+ extension = "csv";
3451
+ }
3452
+ if (format === "tsv") {
3453
+ mime = "text/tab-separated-values;charset=utf-8";
3454
+ extension = "tsv";
3455
+ }
3456
+ }
3457
+ if (format === "html")
3458
+ html = `<table><thead><tr>${columns.map((c) => `<th>${escapeHtml(c.label)}</th>`).join("")}</tr></thead><tbody>${payload.rows.map((row) => `<tr>${columns.map((c) => `<td>${escapeHtml(columnCell(row, c)).replace(/\r\n|\r|\n/g, "<br>")}</td>`).join("")}</tr>`).join("")}</tbody></table>`;
3459
+ } else {
3460
+ plainText = payload.kind === "text" || payload.kind === "markdown" ? payload.text : stringifyJson(payload.value, { style: "pretty" });
3461
+ if (format === "markdown") {
3462
+ mime = "text/markdown;charset=utf-8";
3463
+ extension = "md";
3464
+ }
3465
+ if (format === "html") html = `<pre>${escapeHtml(plainText)}</pre>`;
3466
+ }
3467
+ if (format === "html") {
3468
+ mime = "text/html;charset=utf-8";
3469
+ extension = "html";
3470
+ }
3471
+ return sealTransferArtifact({
3472
+ snapshotId: draft.snapshotId,
3473
+ draftRevision: draft.revision,
3474
+ format,
3475
+ plainText,
3476
+ ...html === void 0 ? {} : { html },
3477
+ file: {
3478
+ filename: options.filename ?? `export.${extension}`,
3479
+ mime,
3480
+ bytes: new TextEncoder().encode(
3481
+ format === "html" ? html ?? plainText : plainText
3482
+ )
3483
+ },
3484
+ omissions
3485
+ });
3486
+ }
3487
+ async function renderMarkdownHtml(markdown) {
3488
+ const [{ marked }, purify] = await Promise.all([
3489
+ import("marked"),
3490
+ import("dompurify")
3491
+ ]);
3492
+ const html = await marked.parse(markdown);
3493
+ const api = purify.default;
3494
+ if (typeof api === "function" && typeof window !== "undefined") {
3495
+ const purifier = api(window);
3496
+ if (typeof purifier?.sanitize === "function") return purifier.sanitize(html);
3497
+ }
3498
+ if (typeof api.sanitize === "function")
3499
+ return api.sanitize(html);
3500
+ throw new ContentTransferError(
3501
+ "rich-html-unavailable",
3502
+ "Rich Markdown HTML requires a DOMPurify DOM adapter"
3503
+ );
3504
+ }
3505
+ async function serializeMarkdownRich(d, filename = "export.html") {
3506
+ if (d.payload.kind !== "markdown")
3507
+ throw new ContentTransferError(
3508
+ "unsupported-format",
3509
+ "Rich Markdown requires Markdown payload"
3510
+ );
3511
+ const html = await renderMarkdownHtml(d.payload.text);
3512
+ return sealTransferArtifact({
3513
+ snapshotId: d.snapshotId,
3514
+ draftRevision: d.revision,
3515
+ format: "html",
3516
+ plainText: d.payload.text,
3517
+ html,
3518
+ file: {
3519
+ filename,
3520
+ mime: "text/html;charset=utf-8",
3521
+ bytes: new TextEncoder().encode(html)
3522
+ },
3523
+ omissions: [...d.omissions]
3524
+ });
3525
+ }
3526
+ function createBrowserTransport() {
3527
+ return {
3528
+ async copy(a, signal) {
3529
+ const cancelled = () => signal.aborted ? { status: "cancelled" } : void 0;
3530
+ try {
3531
+ if (cancelled()) return cancelled();
3532
+ const c = globalThis.navigator?.clipboard;
3533
+ if (!c?.write && !c?.writeText)
3534
+ return {
3535
+ status: "error",
3536
+ code: "clipboard-unavailable",
3537
+ message: "Clipboard writing is unavailable",
3538
+ retryable: false
3539
+ };
3540
+ if (a.html && c.write && typeof globalThis.ClipboardItem === "function") {
3541
+ try {
3542
+ await c.write([
3543
+ new ClipboardItem({
3544
+ "text/plain": new Blob([a.plainText], { type: "text/plain" }),
3545
+ "text/html": new Blob([a.html], { type: "text/html" })
3546
+ })
3547
+ ]);
3548
+ if (cancelled()) return cancelled();
3549
+ return {
3550
+ status: "success",
3551
+ delivered: "clipboard",
3552
+ mimeTypes: ["text/plain", "text/html"]
3553
+ };
3554
+ } catch {
3555
+ if (cancelled()) return cancelled();
3556
+ }
3557
+ }
3558
+ if (c.writeText) {
3559
+ await c.writeText(a.plainText);
3560
+ if (cancelled()) return cancelled();
3561
+ return a.html ? {
3562
+ status: "degraded",
3563
+ delivered: "plain-text",
3564
+ reason: "Rich clipboard write was unavailable or rejected"
3565
+ } : {
3566
+ status: "success",
3567
+ delivered: "clipboard",
3568
+ mimeTypes: ["text/plain"]
3569
+ };
3570
+ }
3571
+ return {
3572
+ status: "error",
3573
+ code: "clipboard-rejected",
3574
+ message: "Clipboard rejected the write",
3575
+ retryable: true
3576
+ };
3577
+ } catch (e) {
3578
+ return cancelled() ?? {
3579
+ status: "error",
3580
+ code: "clipboard-rejected",
3581
+ message: e instanceof Error ? e.message : "Clipboard rejected the write",
3582
+ retryable: true
3583
+ };
3584
+ }
3585
+ },
3586
+ async download(a, signal) {
3587
+ if (signal.aborted) return { status: "cancelled" };
3588
+ if (!a.file || typeof document === "undefined" || !URL?.createObjectURL)
3589
+ return {
3590
+ status: "error",
3591
+ code: "download-unavailable",
3592
+ message: "Download is unavailable",
3593
+ retryable: false
3594
+ };
3595
+ let url;
3596
+ try {
3597
+ url = URL.createObjectURL(
3598
+ new Blob([a.file.bytes.slice().buffer], {
3599
+ type: a.file.mime
3600
+ })
3601
+ );
3602
+ const link = document.createElement("a");
3603
+ link.href = url;
3604
+ link.download = a.file.filename;
3605
+ link.click();
3606
+ return signal.aborted ? { status: "cancelled" } : {
3607
+ status: "success",
3608
+ delivered: "download-started",
3609
+ mimeTypes: [a.file.mime]
3610
+ };
3611
+ } catch (e) {
3612
+ return signal.aborted ? { status: "cancelled" } : {
3613
+ status: "error",
3614
+ code: "download-failed",
3615
+ message: e instanceof Error ? e.message : "Download failed",
3616
+ retryable: true
3617
+ };
3618
+ } finally {
3619
+ if (url) setTimeout(() => URL.revokeObjectURL(url), 0);
3620
+ }
3621
+ }
3622
+ };
3623
+ }
3624
+ function assertLimit(value, name) {
3625
+ if (value != null && (!Number.isSafeInteger(value) || value < 0)) {
3626
+ throw new ContentTransferError(
3627
+ "invalid-limit",
3628
+ `${name} must be a non-negative safe integer or null`
3629
+ );
3630
+ }
3631
+ }
3632
+ var limitKeys = [
3633
+ "maxRows",
3634
+ "maxStringChars",
3635
+ "maxDepth",
3636
+ "maxArrayItems",
3637
+ "targetTokens"
3638
+ ];
3639
+ function resolveTransferPreferences(provider = {}, menu = {}, sourceLimits = {}) {
3640
+ const limits = {
3641
+ maxRows: null,
3642
+ maxStringChars: null,
3643
+ maxDepth: null,
3644
+ maxArrayItems: null,
3645
+ targetTokens: null
3646
+ };
3647
+ for (const key of limitKeys) {
3648
+ const candidates = [
3649
+ provider.limits?.[key],
3650
+ menu.limits?.[key],
3651
+ sourceLimits[key]
3652
+ ];
3653
+ candidates.forEach((value) => assertLimit(value, key));
3654
+ const finite = candidates.filter((value) => value != null);
3655
+ limits[key] = finite.length ? Math.min(...finite) : null;
3656
+ }
3657
+ return deepFreeze({
3658
+ initialFormat: menu.initialFormat ?? provider.initialFormat ?? "plain",
3659
+ initialPreset: menu.initialPreset ?? provider.initialPreset ?? "full",
3660
+ limits
3661
+ });
3662
+ }
3663
+ function cloneTransferRegistration(value, path = "registration", seen = /* @__PURE__ */ new WeakSet()) {
3664
+ if (value === null || typeof value !== "object" && typeof value !== "function")
3665
+ return value;
3666
+ if (typeof value === "function") return value;
3667
+ if (seen.has(value))
3668
+ throw new ContentTransferError(
3669
+ "unsupported-registration-metadata",
3670
+ "Circular transfer registration metadata is unsupported",
3671
+ path
3672
+ );
3673
+ seen.add(value);
3674
+ if (Array.isArray(value)) {
3675
+ const copy2 = value.map(
3676
+ (item, index) => cloneTransferRegistration(item, `${path}/${index}`, seen)
3677
+ );
3678
+ seen.delete(value);
3679
+ return Object.freeze(copy2);
3680
+ }
3681
+ const prototype = Object.getPrototypeOf(value);
3682
+ if (prototype !== Object.prototype && prototype !== null)
3683
+ throw new ContentTransferError(
3684
+ "unsupported-registration-metadata",
3685
+ "Transfer registration metadata must use plain objects and arrays",
3686
+ path
3687
+ );
3688
+ const copy = Object.create(prototype);
3689
+ for (const key of Reflect.ownKeys(value)) {
3690
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
3691
+ if (!("value" in descriptor))
3692
+ throw new ContentTransferError(
3693
+ "unsupported-registration-metadata",
3694
+ "Transfer registration metadata cannot use accessors",
3695
+ `${path}/${String(key)}`
3696
+ );
3697
+ Object.defineProperty(copy, key, {
3698
+ value: cloneTransferRegistration(
3699
+ descriptor.value,
3700
+ `${path}/${String(key)}`,
3701
+ seen
3702
+ ),
3703
+ enumerable: descriptor.enumerable === true,
3704
+ writable: false,
3705
+ configurable: false
3706
+ });
3707
+ }
3708
+ seen.delete(value);
3709
+ return Object.freeze(copy);
3710
+ }
3711
+ function resolveTransferRegistry(...groups) {
3712
+ const ids = /* @__PURE__ */ new Set();
3713
+ const result = [];
3714
+ for (const group of groups)
3715
+ for (const item of group) {
3716
+ const copy = cloneTransferRegistration(item);
3717
+ if (!copy.id.trim() || ids.has(copy.id))
3718
+ throw new ContentTransferError(
3719
+ "duplicate-registration",
3720
+ `Transfer id ${JSON.stringify(copy.id)} is empty or registered more than once`
3721
+ );
3722
+ ids.add(copy.id);
3723
+ result.push(copy);
3724
+ }
3725
+ return Object.freeze(result);
3726
+ }
3727
+ function createSurfaceTransferHandle(options) {
3728
+ const declarations = resolveTransferRegistry(
3729
+ options.manifest.values.map((value) => ({ ...value, id: value.name }))
3730
+ );
3731
+ return {
3732
+ instanceId: options.instanceId,
3733
+ surfaceName: options.manifest.surfaceName,
3734
+ isMounted: options.isMounted,
3735
+ async capture(signal) {
3736
+ stop(signal);
3737
+ if (!options.isMounted())
3738
+ throw new ContentTransferError(
3739
+ "surface-unmounted",
3740
+ "The captured surface is no longer mounted"
3741
+ );
3742
+ const revisionBefore = options.getRevision?.();
3743
+ const scope = await options.getScope();
3744
+ stop(signal);
3745
+ if (!options.isMounted())
3746
+ throw new ContentTransferError(
3747
+ "surface-unmounted",
3748
+ "The surface closed during capture"
3749
+ );
3750
+ if (revisionBefore !== void 0 && options.getRevision?.() !== revisionBefore)
3751
+ throw new ContentTransferError(
3752
+ "surface-changed",
3753
+ "The surface changed during capture; capture again"
3754
+ );
3755
+ const value = {};
3756
+ for (const declaration of declarations) {
3757
+ if (Object.hasOwn(scope, declaration.name) && scope[declaration.name] !== void 0) {
3758
+ Object.defineProperty(value, declaration.name, {
3759
+ value: clone(
3760
+ scope[declaration.name],
3761
+ `/${enc(declaration.name)}`
3762
+ ),
3763
+ enumerable: true,
3764
+ writable: true,
3765
+ configurable: true
3766
+ });
3767
+ }
3768
+ }
3769
+ return directSource(
3770
+ { kind: "json", value },
3771
+ {
3772
+ sourceId: options.instanceId,
3773
+ revision: revisionBefore ?? uid(),
3774
+ label: options.manifest.label ?? options.manifest.surfaceName,
3775
+ unsavedChanges: options.unsavedChanges?.() ?? false,
3776
+ sections: declarations.filter((d) => Object.hasOwn(value, d.name)).map((d) => ({
3777
+ id: d.name,
3778
+ label: d.label,
3779
+ path: `/${enc(d.name)}`,
3780
+ includedByDefault: d.includedByDefault ?? true
3781
+ })),
3782
+ projection: {
3783
+ rules: [
3784
+ ...options.projection?.rules ?? [],
3785
+ ...declarations.map((d) => ({
3786
+ target: "payload",
3787
+ path: `/${enc(d.name)}`,
3788
+ exportable: d.exportable ?? true,
3789
+ classification: d.classification ?? "ordinary"
3790
+ }))
3791
+ ]
3792
+ },
3793
+ ...options.limits ? { limits: options.limits } : {}
3794
+ }
3795
+ );
3796
+ }
3797
+ };
3798
+ }
3799
+ function limitJson(value, limits, omissions, path = "", depth = 0) {
3800
+ if (limits.maxDepth != null && depth > limits.maxDepth) {
3801
+ omissions.push({ path, reason: "truncated" });
3802
+ return null;
3803
+ }
3804
+ if (typeof value === "string" && limits.maxStringChars != null && Array.from(value).length > limits.maxStringChars) {
3805
+ const chars = Array.from(value);
3806
+ omissions.push({
3807
+ path,
3808
+ reason: "truncated",
3809
+ count: chars.length - limits.maxStringChars
3810
+ });
3811
+ return chars.slice(0, limits.maxStringChars).join("");
3812
+ }
3813
+ if (Array.isArray(value)) {
3814
+ const count = Math.min(value.length, limits.maxArrayItems ?? value.length);
3815
+ if (count < value.length)
3816
+ omissions.push({
3817
+ path,
3818
+ reason: "truncated",
3819
+ count: value.length - count
3820
+ });
3821
+ return value.slice(0, count).map(
3822
+ (item, index) => limitJson(item, limits, omissions, `${path}/${index}`, depth + 1)
3823
+ );
3824
+ }
3825
+ if (value && typeof value === "object")
3826
+ return Object.fromEntries(
3827
+ Object.entries(value).map(([key, item]) => [
3828
+ key,
3829
+ limitJson(item, limits, omissions, `${path}/${enc(key)}`, depth + 1)
3830
+ ])
3831
+ );
3832
+ return value;
3833
+ }
3834
+ function limitPayload(payload, limits, omissions) {
3835
+ limitKeys.forEach((key) => assertLimit(limits[key], key));
3836
+ if (payload.kind === "rows") {
3837
+ const count = Math.min(
3838
+ payload.rows.length,
3839
+ limits.maxRows ?? payload.rows.length
3840
+ );
3841
+ if (count < payload.rows.length)
3842
+ omissions.push({
3843
+ path: "/rows",
3844
+ reason: "truncated",
3845
+ count: payload.rows.length - count
3846
+ });
3847
+ return {
3848
+ ...payload,
3849
+ rows: payload.rows.slice(0, count).map(
3850
+ (row, index) => limitJson(row, limits, omissions, `/rows/${index}`)
3851
+ )
3852
+ };
3853
+ }
3854
+ if (payload.kind === "json" || payload.kind === "registered")
3855
+ return { ...payload, value: limitJson(payload.value, limits, omissions) };
3856
+ return {
3857
+ ...payload,
3858
+ text: limitJson(payload.text, limits, omissions)
3859
+ };
3860
+ }
3861
+ function applyTransferLimits(draft, limits) {
3862
+ const omissions = [];
3863
+ const payload = limitPayload(draft.payload, limits, omissions);
3864
+ return omissions.length ? revise(draft, payload, omissions, "Applied preparation limits") : draft;
3865
+ }
2722
3866
  export {
3867
+ ContentTransferError,
2723
3868
  DBStoreManager,
2724
3869
  DEFAULT_JSON_INDENT,
2725
3870
  DEFAULT_JSON_WIDTH,
@@ -2727,19 +3872,30 @@ export {
2727
3872
  FeatureStore,
2728
3873
  PublicStoreManager,
2729
3874
  _resetIdbStoreSingletons,
3875
+ applySectionSelection,
3876
+ applyTransferLimits,
2730
3877
  booleanUrlCodec,
3878
+ buildAgentPayload,
3879
+ capture,
2731
3880
  captureDrafts,
3881
+ collectAllMatching,
2732
3882
  commitUrlParams,
2733
3883
  computeSearchScore,
3884
+ createBrowserTransport,
2734
3885
  createColorNormalizer,
3886
+ createDraft,
2735
3887
  createFormatter,
2736
3888
  createMatrxToast,
3889
+ createSurfaceTransferHandle,
2737
3890
  decodeQrFromElement,
2738
3891
  decodeQrFromImageData,
2739
3892
  decodeQrFromImageFile,
2740
3893
  detectJson,
3894
+ directSource,
2741
3895
  discardDraft,
3896
+ editDraft,
2742
3897
  enumUrlCodec,
3898
+ fenceJsonBlock,
2743
3899
  filterAndSortBySearch,
2744
3900
  findNearestTailwindColor,
2745
3901
  fireInvalidation,
@@ -2783,23 +3939,38 @@ export {
2783
3939
  jsonUrlCodec,
2784
3940
  listDrafts,
2785
3941
  matchesSearch,
3942
+ normalizeTransferJson,
2786
3943
  onFlushComplete,
2787
3944
  parseHexOrRgb,
2788
3945
  positiveIntegerUrlCodec,
3946
+ projectSnapshot,
3947
+ readTransferCell,
3948
+ reduceJson,
3949
+ refreshDraft,
2789
3950
  registerDraftSource,
2790
3951
  registerIdleTask,
2791
3952
  registerInvalidationCallback,
3953
+ renderMarkdownHtml,
2792
3954
  reportDelimiterViolations,
3955
+ resetDraft,
2793
3956
  resetScheduler,
3957
+ resolveTransferPreferences,
3958
+ resolveTransferRegistry,
2794
3959
  rgbDelta,
2795
3960
  rgbToLab,
2796
3961
  runWithConcurrency,
3962
+ sealTransferArtifact,
3963
+ serialize,
3964
+ serializeMarkdownRich,
2797
3965
  setUrlStateRouter,
3966
+ sourceChanged,
2798
3967
  stringUrlCodec,
2799
3968
  stringifyJson,
2800
3969
  subscribeDrafts,
2801
3970
  tailwindColors,
3971
+ transformRows,
2802
3972
  treeContainsComponent,
3973
+ undoDraft,
2803
3974
  useAutosave,
2804
3975
  useClipboard,
2805
3976
  useDurableDraft,