@songsid/agend 2.3.3-beta.9 → 2.3.4-beta.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/README.md +3 -3
- package/README.zh-TW.md +3 -3
- package/dist/agent-cli-instructions.md +1 -1
- package/dist/auth-api.d.ts +16 -3
- package/dist/auth-api.js +22 -6
- package/dist/auth-api.js.map +1 -1
- package/dist/authority/web-authority.d.ts +15 -1
- package/dist/authority/web-authority.js +27 -10
- package/dist/authority/web-authority.js.map +1 -1
- package/dist/backend/claude-code.js +11 -1
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/codex.js +12 -0
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/types.d.ts +7 -0
- package/dist/backend/types.js.map +1 -1
- package/dist/config-validator.js +18 -1
- package/dist/config-validator.js.map +1 -1
- package/dist/daemon.js +8 -1
- package/dist/daemon.js.map +1 -1
- package/dist/env-file.d.ts +2 -0
- package/dist/env-file.js +13 -8
- package/dist/env-file.js.map +1 -1
- package/dist/fleet-manager.d.ts +41 -1
- package/dist/fleet-manager.js +179 -22
- package/dist/fleet-manager.js.map +1 -1
- package/dist/general-knowledge/skills/cross-instance-messaging/SKILL.md +1 -1
- package/dist/general-knowledge/skills/web-dashboard/SKILL.md +4 -0
- package/dist/general-knowledge/skills/worker-collaboration/SKILL.md +1 -1
- package/dist/instance-config-impact.js +1 -0
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/instance-lifecycle.d.ts +2 -0
- package/dist/instance-lifecycle.js +23 -7
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/instructions.d.ts +1 -1
- package/dist/instructions.js +1 -1
- package/dist/instructions.js.map +1 -1
- package/dist/interaction-observation.d.ts +1 -0
- package/dist/interaction-observation.js +1 -1
- package/dist/interaction-observation.js.map +1 -1
- package/dist/locale.js +56 -2
- package/dist/locale.js.map +1 -1
- package/dist/next-steps.d.ts +12 -2
- package/dist/next-steps.js +19 -3
- package/dist/next-steps.js.map +1 -1
- package/dist/office-share-service.d.ts +57 -0
- package/dist/office-share-service.js +76 -11
- package/dist/office-share-service.js.map +1 -1
- package/dist/office-share.d.ts +8 -0
- package/dist/office-share.js +34 -0
- package/dist/office-share.js.map +1 -1
- package/dist/outbound-schemas.js +1 -1
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/page-share.d.ts +122 -0
- package/dist/page-share.js +199 -0
- package/dist/page-share.js.map +1 -0
- package/dist/public-link-progress.d.ts +5 -2
- package/dist/public-link-progress.js +4 -3
- package/dist/public-link-progress.js.map +1 -1
- package/dist/public-preview.d.ts +4 -0
- package/dist/public-preview.js +5 -4
- package/dist/public-preview.js.map +1 -1
- package/dist/public-web-gateway.js +5 -0
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/public-web-link.d.ts +10 -0
- package/dist/public-web-link.js +24 -5
- package/dist/public-web-link.js.map +1 -1
- package/dist/quickstart-api.d.ts +5 -0
- package/dist/quickstart-api.js +1 -1
- package/dist/quickstart-api.js.map +1 -1
- package/dist/quickstart.d.ts +40 -0
- package/dist/quickstart.js +174 -28
- package/dist/quickstart.js.map +1 -1
- package/dist/remote-card-answer.js +2 -0
- package/dist/remote-card-answer.js.map +1 -1
- package/dist/remote-card-prompt.js +4 -2
- package/dist/remote-card-prompt.js.map +1 -1
- package/dist/selection-card.d.ts +21 -0
- package/dist/selection-card.js +129 -0
- package/dist/selection-card.js.map +1 -0
- package/dist/settings-api.d.ts +10 -0
- package/dist/settings-api.js +45 -0
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-change.js +5 -0
- package/dist/settings-change.js.map +1 -1
- package/dist/settings-effect.js +2 -0
- package/dist/settings-effect.js.map +1 -1
- package/dist/setup-host.js +2 -2
- package/dist/setup-host.js.map +1 -1
- package/dist/setup-wizard.js +2 -2
- package/dist/setup-wizard.js.map +1 -1
- package/dist/tunnel/cloudflared.d.ts +5 -0
- package/dist/tunnel/cloudflared.js +32 -1
- package/dist/tunnel/cloudflared.js.map +1 -1
- package/dist/tunnel/named-diagnostics.d.ts +2 -1
- package/dist/tunnel/named-diagnostics.js +4 -1
- package/dist/tunnel/named-diagnostics.js.map +1 -1
- package/dist/tunnel/named-link-test.d.ts +90 -0
- package/dist/tunnel/named-link-test.js +270 -0
- package/dist/tunnel/named-link-test.js.map +1 -0
- package/dist/tunnel/purpose-lane.d.ts +3 -1
- package/dist/tunnel/purpose-lane.js +2 -0
- package/dist/tunnel/purpose-lane.js.map +1 -1
- package/dist/types.d.ts +10 -0
- package/dist/ui/chat-store.js +8 -1
- package/dist/ui/chat-strings.js +36 -0
- package/dist/ui/page-share-dialog.js +191 -0
- package/dist/ui/panel-chat.js +14 -0
- package/dist/ui/panel-notices.js +98 -0
- package/dist/ui/panel-settings.js +14 -5
- package/dist/ui/preview-pages.js +41 -0
- package/dist/ui/preview-panel-actions.js +161 -0
- package/dist/ui/preview-panel.js +209 -28
- package/dist/ui/preview-versions.js +155 -0
- package/dist/ui/preview.js +88 -3
- package/dist/ui/settings-named-test.js +144 -0
- package/dist/ui/settings-registry.js +1 -0
- package/dist/ui/settings-strings.js +10 -6
- package/dist/ui/shared/app-i18n.js +2 -2
- package/dist/ui/shared/app-route.js +4 -0
- package/dist/ui/shared/app-shell.js +5 -3
- package/dist/ui/shared/app-store.js +71 -1
- package/dist/ui/shared/app-stream.js +1 -1
- package/dist/ui/shared/app.css +50 -1
- package/dist/ui/shared/app.js +22 -1
- package/dist/ui/shared/signin.js +12 -1
- package/dist/ui/shared/ui-icons.js +3 -0
- package/dist/ui/shared/web-authorize.js +5 -3
- package/dist/web-api.d.ts +26 -0
- package/dist/web-api.js +180 -1
- package/dist/web-api.js.map +1 -1
- package/dist/web-auth.js +7 -1
- package/dist/web-auth.js.map +1 -1
- package/dist/web-login.d.ts +2 -0
- package/dist/web-login.js +3 -1
- package/dist/web-login.js.map +1 -1
- package/dist/web-notices.d.ts +51 -0
- package/dist/web-notices.js +118 -0
- package/dist/web-notices.js.map +1 -0
- package/dist/web-only-fleet.d.ts +22 -0
- package/dist/web-only-fleet.js +13 -0
- package/dist/web-only-fleet.js.map +1 -0
- package/dist/web-preview.d.ts +32 -3
- package/dist/web-preview.js +52 -19
- package/dist/web-preview.js.map +1 -1
- package/dist/web-session.d.ts +7 -0
- package/dist/web-session.js +2 -0
- package/dist/web-session.js.map +1 -1
- package/dist/web-settings-patch.d.ts +3 -1
- package/dist/web-settings-patch.js +4 -1
- package/dist/web-settings-patch.js.map +1 -1
- package/dist/web-shell-routes.d.ts +2 -0
- package/dist/web-shell-routes.js +3 -0
- package/dist/web-shell-routes.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* #2910 D4: a CLI's own numbered-choice dialog (Claude Code's Bash or tool permission, its trust / Bypass screens it
|
|
3
|
+
* did not recognise, "Background work is running", "Switch model?"; Codex's selections; any numbered prompt the
|
|
4
|
+
* #1691 catch-all holds), read from the pane as a #2675 question card — so that on a web-only fleet the person answers it
|
|
5
|
+
* from the dashboard: the card's own options as buttons, keyed in by remote-card-answer.ts on a verified cursor.
|
|
6
|
+
*
|
|
7
|
+
* Pure. Bottom-anchored like unrecognised-prompt.ts: the cursor (`❯`/`›`) is on a numbered option in a run of
|
|
8
|
+
* consecutive options at the bottom of the screen (at most a short footer below), so a transcript quoting a dialog is
|
|
9
|
+
* never one. The dialog's own words above the options (up to its top border) are its question — what a person needs to
|
|
10
|
+
* decide (for a Bash permission: the command and its description). Esc is never offered: on some of these dialogs it is
|
|
11
|
+
* not a harmless skip (Claude's trust screen exits the CLI), and the dialog's own options say every choice there is.
|
|
12
|
+
*/
|
|
13
|
+
import type { RemoteQuestionCard } from "./backend/types.js";
|
|
14
|
+
/** Rows of the dialog's words kept, and their length. */
|
|
15
|
+
export declare const SELECTION_BODY_LINES = 10;
|
|
16
|
+
export declare const SELECTION_LINE_MAX = 200;
|
|
17
|
+
/**
|
|
18
|
+
* The numbered-choice dialog at the bottom of `pane`, as a question card titled `title` (the CLI's name), or null.
|
|
19
|
+
* `rowWidth` is unused here (no typed answer); the card offers no Esc (`noSkip`) and is posted only on a web-only fleet.
|
|
20
|
+
*/
|
|
21
|
+
export declare function selectionCard(pane: string, title: string): RemoteQuestionCard | null;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
const ANSI = /\x1b\[[0-9;?]*[ -/]*[@-~]|\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)/g;
|
|
2
|
+
const CURSOR_OPTION = /^([ \t]*)[❯›][ \t]*(\d{1,2})[.)][ \t]+(\S.*)$/;
|
|
3
|
+
const OPTION = /^([ \t]*)(?:[❯›][ \t]*)?(\d{1,2})[.)][ \t]+(\S.*)$/;
|
|
4
|
+
/**
|
|
5
|
+
* The dialog's own top border: a plain rule (Claude's `─`/`▔`). Never a box row with corners (`╭─…╮`, `╰─…╯`): that is
|
|
6
|
+
* Codex's session header above the transcript, not the top of a dialog (#2928 review).
|
|
7
|
+
*/
|
|
8
|
+
const BORDER = /^[ \t]*[─━═▔▁]{8,}[ \t]*$/;
|
|
9
|
+
/** A box's top or bottom row (Codex's session header): what is above or in it is never the dialog's words — reading stops. */
|
|
10
|
+
const BOX_EDGE = /^[ \t]*[╭╰┌└][─━═]{6,}[╮╯┐┘]?[ \t]*$/;
|
|
11
|
+
/** A separator inside the dialog (Claude's dashed rule around a command): skipped, not a boundary. */
|
|
12
|
+
const SEPARATOR = /^[ \t]*[╌┄┈\-]{8,}[ \t]*$/;
|
|
13
|
+
/** A box's side borders around a row (Codex): stripped. */
|
|
14
|
+
const SIDES = /^[ \t]*[│┃][ \t]?(.*?)[ \t]*[│┃]?[ \t]*$/;
|
|
15
|
+
/** Rows a dialog may have below its last option (a hint footer: "Esc to cancel · Tab to amend"). */
|
|
16
|
+
const FOOTER_ROWS = 3;
|
|
17
|
+
/** How far above the first option the dialog's words are read. */
|
|
18
|
+
const BODY_ROWS = 14;
|
|
19
|
+
/** Rows of the dialog's words kept, and their length. */
|
|
20
|
+
export const SELECTION_BODY_LINES = 10;
|
|
21
|
+
export const SELECTION_LINE_MAX = 200;
|
|
22
|
+
/** An option's text, at most. */
|
|
23
|
+
const OPTION_MAX = 160;
|
|
24
|
+
function clean(raw, max = SELECTION_LINE_MAX) {
|
|
25
|
+
const text = raw.replace(/[\x00-\x1f\x7f]/g, " ").replace(/\s+/g, " ").trim();
|
|
26
|
+
return text.length > max ? `${text.slice(0, max - 1)}…` : text;
|
|
27
|
+
}
|
|
28
|
+
/** A countdown in the dialog's words ("auto-deny in 30s", "block this request in 1:55") never makes the card another card. */
|
|
29
|
+
const COUNTDOWN = /\b\d+\s*(?:s|sec|secs|seconds?)\b|\b\d{1,2}:\d{2}\b/gi;
|
|
30
|
+
/**
|
|
31
|
+
* The numbered-choice dialog at the bottom of `pane`, as a question card titled `title` (the CLI's name), or null.
|
|
32
|
+
* `rowWidth` is unused here (no typed answer); the card offers no Esc (`noSkip`) and is posted only on a web-only fleet.
|
|
33
|
+
*/
|
|
34
|
+
export function selectionCard(pane, title) {
|
|
35
|
+
const rows = pane.replace(ANSI, "").replace(/\r/g, "").split("\n").map(r => r.trimEnd()).map(r => SIDES.exec(r)?.[1] ?? r);
|
|
36
|
+
let lastFilled = rows.length - 1;
|
|
37
|
+
while (lastFilled >= 0 && rows[lastFilled].trim() === "")
|
|
38
|
+
lastFilled--;
|
|
39
|
+
if (lastFilled < 0)
|
|
40
|
+
return null;
|
|
41
|
+
// The cursor row: the lowest one, within the bottom of the screen.
|
|
42
|
+
let at = -1;
|
|
43
|
+
for (let i = lastFilled, filled = 0; i >= 0 && filled < 24; i--) {
|
|
44
|
+
if (rows[i].trim() === "")
|
|
45
|
+
continue;
|
|
46
|
+
filled++;
|
|
47
|
+
if (CURSOR_OPTION.test(rows[i])) {
|
|
48
|
+
at = i;
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (at < 0)
|
|
53
|
+
return null;
|
|
54
|
+
// The run of options around it: numbered rows, each perhaps continued on deeper-indented rows (a wrapped option).
|
|
55
|
+
const indentOf = (r) => (/^[ \t]*/.exec(r)[0].length);
|
|
56
|
+
const optionIndent = indentOf(rows[at].replace(/[❯›]/, " "));
|
|
57
|
+
const isOption = (r) => OPTION.test(r) && Math.abs(indentOf(r.replace(/[❯›]/, " ")) - optionIndent) <= 2;
|
|
58
|
+
const isContinuation = (r) => r.trim() !== "" && !OPTION.test(r) && indentOf(r) > optionIndent;
|
|
59
|
+
let first = at;
|
|
60
|
+
for (let i = at - 1; i >= 0; i--) {
|
|
61
|
+
if (isOption(rows[i])) {
|
|
62
|
+
first = i;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (isContinuation(rows[i]) && i > 0 && (isOption(rows[i - 1]) || isContinuation(rows[i - 1])))
|
|
66
|
+
continue;
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
let last = at;
|
|
70
|
+
for (let i = at + 1; i < rows.length; i++) {
|
|
71
|
+
if (isOption(rows[i]) || (isContinuation(rows[i]) && last === i - 1)) {
|
|
72
|
+
last = i;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
let below = 0;
|
|
78
|
+
for (let i = last + 1; i <= lastFilled; i++)
|
|
79
|
+
if (rows[i].trim() !== "")
|
|
80
|
+
below++;
|
|
81
|
+
if (below > FOOTER_ROWS)
|
|
82
|
+
return null;
|
|
83
|
+
const options = [];
|
|
84
|
+
let cursor = null;
|
|
85
|
+
for (let i = first; i <= last; i++) {
|
|
86
|
+
const m = OPTION.exec(rows[i]);
|
|
87
|
+
if (m && isOption(rows[i])) {
|
|
88
|
+
if (CURSOR_OPTION.test(rows[i]))
|
|
89
|
+
cursor = options.length;
|
|
90
|
+
options.push({ n: Number(m[2]), title: m[3], recommended: false, description: null });
|
|
91
|
+
}
|
|
92
|
+
else if (options.length) {
|
|
93
|
+
options[options.length - 1].title += ` ${rows[i].trim()}`;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (options.length < 2 || cursor === null || !options.every((o, i) => o.n === i + 1))
|
|
97
|
+
return null;
|
|
98
|
+
for (const o of options)
|
|
99
|
+
o.title = clean(o.title, OPTION_MAX);
|
|
100
|
+
// The dialog's words: up from the first option to its top border (Claude's plain rule — its words may hold a double blank
|
|
101
|
+
// row, as the dangerous-rm dialog does), separators skipped; a dialog with no such border (Codex) ends at a double blank
|
|
102
|
+
// row — never the transcript above it (#2928 review).
|
|
103
|
+
let border = -1;
|
|
104
|
+
for (let i = first - 1; i >= 0 && first - i <= BODY_ROWS; i--)
|
|
105
|
+
if (BORDER.test(rows[i])) {
|
|
106
|
+
border = i;
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
const body = [];
|
|
110
|
+
for (let i = first - 1, blanks = 0; i > border && first - i <= BODY_ROWS; i--) {
|
|
111
|
+
const r = rows[i];
|
|
112
|
+
if (r.trim() === "") {
|
|
113
|
+
if (border < 0 && ++blanks >= 2 && body.length)
|
|
114
|
+
break;
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
blanks = 0;
|
|
118
|
+
if (BOX_EDGE.test(r))
|
|
119
|
+
break;
|
|
120
|
+
if (SEPARATOR.test(r))
|
|
121
|
+
continue;
|
|
122
|
+
body.unshift(clean(r));
|
|
123
|
+
}
|
|
124
|
+
const words = body.slice(-SELECTION_BODY_LINES);
|
|
125
|
+
const question = words.join("\n");
|
|
126
|
+
const identity = ["selection", title, question.replace(COUNTDOWN, "#s"), ...options.map(o => `${o.n}. ${o.title.replace(COUNTDOWN, "#s")}`)].join("\n");
|
|
127
|
+
return { kind: "question", identity, title, question, page: "options", options, freeText: false, cursor, typed: null, rowWidth: 0, noSkip: true, webOnly: true };
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=selection-card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selection-card.js","sourceRoot":"","sources":["../src/selection-card.ts"],"names":[],"mappings":"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"}
|
package/dist/settings-api.d.ts
CHANGED
|
@@ -40,6 +40,16 @@ export interface SettingsApiContext extends AppShellContext {
|
|
|
40
40
|
queued: boolean;
|
|
41
41
|
already_running?: boolean;
|
|
42
42
|
};
|
|
43
|
+
/** #2906: the fixed address's Test connection (closed step codes only; never the token). */
|
|
44
|
+
testNamedLink?(input: {
|
|
45
|
+
hostname: unknown;
|
|
46
|
+
port: unknown;
|
|
47
|
+
protocol: unknown;
|
|
48
|
+
token?: unknown;
|
|
49
|
+
current?: () => boolean;
|
|
50
|
+
}): Promise<import("./tunnel/named-link-test.js").NamedTestResult | {
|
|
51
|
+
busy: true;
|
|
52
|
+
}>;
|
|
43
53
|
/** #1920 phase 3: Settings → Web sign-ins → Guests. */
|
|
44
54
|
guestOverview?(): unknown;
|
|
45
55
|
/** #2667: the ClassicBot rooms' instance names — a guest grant may name one, so a save's validation knows them. */
|
package/dist/settings-api.js
CHANGED
|
@@ -346,6 +346,47 @@ export function handleSettingsRequest(req, res, url, ctx) {
|
|
|
346
346
|
}
|
|
347
347
|
return true;
|
|
348
348
|
}
|
|
349
|
+
// #2906 (the user, 2026-11-01): Settings → Access → Test connection, on the fixed-address values as filled in. Admin
|
|
350
|
+
// only and never over the public link, like the rest of Access; the typed token is read from the body once, used
|
|
351
|
+
// only in the test connector's environment, and never echoed — the answer is closed step codes.
|
|
352
|
+
if (method === "POST" && path === "/api/settings/public-link/test") {
|
|
353
|
+
if (gatewayRequestContext(req)) {
|
|
354
|
+
json(res, 403, { error: "web_settings_not_over_public_link" }, true);
|
|
355
|
+
return true;
|
|
356
|
+
}
|
|
357
|
+
const caller = guestSettingsCaller(req, url, ctx);
|
|
358
|
+
if (!caller) {
|
|
359
|
+
json(res, 403, { error: "An admin sign-in is required" }, true);
|
|
360
|
+
return true;
|
|
361
|
+
}
|
|
362
|
+
if (!ctx.testNamedLink) {
|
|
363
|
+
json(res, 501, { error: "test unavailable" }, true);
|
|
364
|
+
return true;
|
|
365
|
+
}
|
|
366
|
+
// #2907 review: the same admin, still current, after the body's await — and again before anything is started.
|
|
367
|
+
const current = () => guestSettingsCaller(req, url, ctx) === caller;
|
|
368
|
+
readBody(req, 16 * 1024).then(async (buf) => {
|
|
369
|
+
if (!permitWebContinuation(req, res, ctx))
|
|
370
|
+
return;
|
|
371
|
+
if (!current())
|
|
372
|
+
return json(res, 401, { error: "no longer authorized" }, true);
|
|
373
|
+
let body;
|
|
374
|
+
try {
|
|
375
|
+
body = JSON.parse(buf.toString("utf-8") || "{}");
|
|
376
|
+
}
|
|
377
|
+
catch {
|
|
378
|
+
return json(res, 400, { error: "invalid JSON" }, true);
|
|
379
|
+
}
|
|
380
|
+
if (!body || typeof body !== "object" || Array.isArray(body))
|
|
381
|
+
return json(res, 400, { error: "invalid body" }, true);
|
|
382
|
+
const result = await ctx.testNamedLink({ hostname: body.hostname, port: body.origin_port, protocol: body.protocol, token: body.token, current });
|
|
383
|
+
if ("busy" in result)
|
|
384
|
+
return json(res, 409, { error: "test_running" }, true);
|
|
385
|
+
json(res, 200, { steps: result.steps, hostname: result.hostname, port: result.port, ...(result.cleanup ? { cleanup: result.cleanup } : {}) }, true);
|
|
386
|
+
}).catch(() => { if (!res.headersSent)
|
|
387
|
+
json(res, 400, { error: "bad request" }, true); });
|
|
388
|
+
return true;
|
|
389
|
+
}
|
|
349
390
|
// Generic provider API-key registry. Unlike the legacy connection token
|
|
350
391
|
// routes, this endpoint accepts a code-owned spec id only; env key, origin,
|
|
351
392
|
// auth header and verifier are resolved server-side. The body is consumed
|
|
@@ -923,6 +964,10 @@ export function handleSettingsRequest(req, res, url, ctx) {
|
|
|
923
964
|
web.office_levels = parsed.officeLevels;
|
|
924
965
|
changes.push({ path: ["web", "office_levels"], value: parsed.officeLevels });
|
|
925
966
|
}
|
|
967
|
+
if (parsed.previewCdn !== undefined) {
|
|
968
|
+
web.preview_cdn = parsed.previewCdn;
|
|
969
|
+
changes.push({ path: ["web", "preview_cdn"], value: parsed.previewCdn });
|
|
970
|
+
}
|
|
926
971
|
if (parsed.publicLink) {
|
|
927
972
|
if (Object.keys(parsed.publicLink).length)
|
|
928
973
|
web.public_link = { ...web.public_link, ...parsed.publicLink };
|