@synopackageland/sdk 0.10.2 → 0.10.3

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.
Files changed (47) hide show
  1. package/README.md +77 -5
  2. package/dist/i18n/background/zh-CN.json +6 -6
  3. package/dist/i18n/delegate/de.json +5 -3
  4. package/dist/i18n/delegate/en.json +5 -3
  5. package/dist/i18n/delegate/es.json +5 -3
  6. package/dist/i18n/delegate/fr.json +5 -3
  7. package/dist/i18n/delegate/it.json +5 -3
  8. package/dist/i18n/delegate/ja.json +5 -3
  9. package/dist/i18n/delegate/ko.json +5 -3
  10. package/dist/i18n/delegate/zh-CN.json +5 -3
  11. package/dist/i18n/delegate/zh-TW.json +5 -3
  12. package/dist/i18n/identity/zh-CN.json +5 -5
  13. package/dist/i18n/save/de.json +15 -17
  14. package/dist/i18n/save/en.json +15 -17
  15. package/dist/i18n/save/es.json +15 -17
  16. package/dist/i18n/save/fr.json +15 -17
  17. package/dist/i18n/save/it.json +15 -17
  18. package/dist/i18n/save/ja.json +15 -17
  19. package/dist/i18n/save/ko.json +15 -17
  20. package/dist/i18n/save/zh-CN.json +15 -17
  21. package/dist/i18n/save/zh-TW.json +15 -17
  22. package/dist/index.js +2355 -2348
  23. package/dist/native.js +350 -0
  24. package/dist/src/delegate/BackgroundSavePanel.vue.d.ts +3 -0
  25. package/dist/src/delegate/BackgroundSaveSettings.vue.d.ts +29 -0
  26. package/dist/src/delegate/ExecutorSettings.vue.d.ts +1 -2
  27. package/dist/src/delegate/copy.d.ts +10 -6
  28. package/dist/src/delegate/executor-setup.d.ts +2 -0
  29. package/dist/src/delegate/save-copy.d.ts +30 -36
  30. package/dist/src/delegate/use-executor-setup.d.ts +5 -1
  31. package/dist/src/delegate/use-scope-approval.d.ts +50 -0
  32. package/dist/src/dsm/file-station.d.ts +1 -1
  33. package/dist/src/native/authorization-runtime.d.ts +2 -0
  34. package/dist/src/native/dsm-version.d.ts +6 -0
  35. package/dist/src/native/root-runtime.d.ts +34 -0
  36. package/dist/src/native.d.ts +2 -0
  37. package/dist/src/protocol/v1.d.ts +7 -1
  38. package/dist/src/shell/PageActions.vue.d.ts +13 -0
  39. package/dist/src/shell/app-pages.d.ts +2 -0
  40. package/dist/src/shell/page-actions.d.ts +3 -0
  41. package/dist/src/vue.d.ts +2 -0
  42. package/dist/style.css +1 -1
  43. package/dist/vue.js +1998 -1735
  44. package/package.json +7 -3
  45. package/spec/protocol/v1/README.md +86 -5
  46. package/spec/protocol/v1/errors.json +8 -0
  47. package/spec/protocol/v1/timeouts.json +21 -0
@@ -0,0 +1,50 @@
1
+ import type { Context } from '../context';
2
+ import type { ScopeSelection } from './long-running';
3
+ import type { CapabilityStatus } from './executor-setup';
4
+ import { type ConfirmFailure } from './use-executor-setup';
5
+ export interface ScopeDetail {
6
+ scope_mode?: string;
7
+ preselection?: string;
8
+ selection?: ScopeSelection | null;
9
+ mismatch?: boolean;
10
+ }
11
+ export declare const SCOPE_READBACK_MS = 60000, SCOPE_READBACK_POLL_MS = 1000;
12
+ export declare function useScopeApproval(props: {
13
+ readonly admin: boolean;
14
+ readonly locale?: string;
15
+ readonly ctx?: Pick<Context, 'call'>;
16
+ }, confirmed: () => void): {
17
+ status: import("vue").Ref<CapabilityStatus | undefined, CapabilityStatus | undefined>;
18
+ password: import("vue").Ref<string, string>;
19
+ busy: import("vue").Ref<boolean, boolean>;
20
+ confirming: import("vue").Ref<boolean, boolean>;
21
+ error: import("vue").Ref<boolean, boolean>;
22
+ failure: import("vue").Ref<{
23
+ confirm: ConfirmFailure;
24
+ } | {
25
+ reason: string;
26
+ code?: string;
27
+ } | undefined, {
28
+ confirm: ConfirmFailure;
29
+ } | {
30
+ reason: string;
31
+ code?: string;
32
+ } | undefined>;
33
+ scope: import("vue").Ref<ScopeDetail | undefined, ScopeDetail | undefined>;
34
+ chosen: import("vue").Ref<string, string>;
35
+ options: import("vue").ComputedRef<{
36
+ label: string;
37
+ value: string;
38
+ }[]>;
39
+ dynamic: import("vue").ComputedRef<boolean>;
40
+ files: import("vue").ComputedRef<boolean>;
41
+ canConfirm: import("vue").ComputedRef<boolean>;
42
+ needsScope: import("vue").ComputedRef<boolean>;
43
+ changed: import("vue").ComputedRef<boolean>;
44
+ refresh: () => Promise<void>;
45
+ authorize: () => Promise<void>;
46
+ explain: (r?: {
47
+ reason?: string;
48
+ code?: string;
49
+ }) => string | undefined;
50
+ };
@@ -21,7 +21,7 @@ export interface FileStationOptions {
21
21
  * stay literal: this is a JS value, not a URL. */
22
22
  export declare function fileStationPath(path: string, mount?: string): string;
23
23
  /** Opens File Station showing the folder. False when nothing was launched:
24
- * outside DSM, an empty path, or File Station disabled or not launchable. */
24
+ * outside DSM, a path that is not one shared-folder path, or File Station disabled or not launchable. */
25
25
  export declare function openFolderInFileStation(path: string, options?: FileStationOptions): boolean;
26
26
  /** Opens File Station at the file's folder with the file selected. False as for openFolderInFileStation. */
27
27
  export declare function openFileInFileStation(path: string, options?: FileStationOptions): boolean;
@@ -0,0 +1,2 @@
1
+ /** Shared host flow. CGI plans are never accepted as completed authorization. */
2
+ export declare const AUTHORIZATION_RUNTIME = "function createAuthorizationAccess(options) {\n var busy = null;\n function fail(code) { var error = new Error(code); error.code = code; return error; }\n function status() { return options.call(\"authorization.status\").then(function (d) {\n if (!d || d.command !== \"authorization\" || d.schema_version !== 1 || [\"ready\",\"authorization_required\",\"not_admin\",\"session_expired\",\"unavailable\"].indexOf(d.state) < 0) throw fail(\"authorization_bad_response\");\n // upgrade_reapproval is a reason-only tombstone: it can only explain a pending request.\n if (d.reason === \"upgrade_reapproval\" && d.state !== \"authorization_required\") throw fail(\"authorization_bad_response\");\n return d;\n }); }\n function plan(method) { return options.call(method).then(function (p) {\n if (!p || p.command !== \"authorization\" || p.schema_version !== 1 || p.phase !== \"plan\" || !Array.isArray(p.operations) || p.operations.length === 0 || p.operations.length > options.tasks.length) throw fail(\"authorization_bad_response\");\n var seen = {};\n p.operations.forEach(function (op) { if (seen[op] || !options.tasks.some(function (t) { return t.op === op; })) throw fail(\"authorization_bad_response\"); seen[op] = true; });\n return p;\n }); }\n // The backend's grant decides: a task still waiting at the window's limit, or\n // one signalled after it wrote the grant, has still authorized the package.\n function settled(e) {\n if (!e || (e.code !== \"root_timeout\" && e.code !== \"root_task_failed\")) throw e;\n return status().then(function (d) { if (d.state !== \"ready\") throw e; });\n }\n function exclusive(fn) { if (busy) return busy; busy = Promise.resolve().then(fn).then(function (s) { busy = null; return s; },function (e) { busy = null; throw e; });return busy; }\n function authorize(ops,run) { return ops.reduce(function (previous,op) { return previous.then(function () {\n return options.root.authorize(op).then(function (state) { if (state !== \"ready\") throw fail(\"root_cancelled\"); return run ? options.root.run(op).catch(settled) : null; });\n }); },Promise.resolve()); }\n return {canManage:function () {return !!options.user && options.user().admin === true;},status:status,request:function () { return exclusive(function () {\n return plan(\"authorization.request\").then(function (p) { return authorize(p.operations,p.run === true); }).then(status,function (e) { if (e.code === \"root_cancelled\") return status();throw e; });\n }); },revoke:function () { return exclusive(function () {\n return plan(\"authorization.revoke\").then(function (p) {\n if (p.withdraw === true && typeof options.withdraw !== \"function\") throw fail(\"authorization_bad_response\");\n var disabled = p.withdraw === true ? options.withdraw() : p.disable === true ? authorize([\"helper_disable\"],true) : Promise.resolve();\n return disabled.then(function () { return p.purge === true ? authorize([\"helper_purge\"],true) : null; }).then(function () { return p.operations.reduce(function (previous,op) {return previous.then(function () {return options.root.remove(op);});},Promise.resolve()); });\n }).then(status,function (e) { if (e.code === \"root_cancelled\") return status();throw e; });\n }); }};\n}";
@@ -0,0 +1,6 @@
1
+ /** Self-contained: the same function is embedded in the DSM window. True only
2
+ * when DSM refused a request because this method version is unavailable, the
3
+ * one refusal that may be retried with an older version. DSM 7.1.1 (t-0234)
4
+ * returns 104 for a version above maxVersion and 103 for a method absent at an
5
+ * existing version. Accepts the numeric code and the window's dsm_ form. */
6
+ export declare function versionUnsupported(code: unknown): boolean;
@@ -0,0 +1,34 @@
1
+ /** Build-time adapter for explicitly approved native product tasks. */
2
+ /** What the window embeds per root operation: the task it may create, and how to recognize it. */
3
+ export interface RootTask {
4
+ op: string;
5
+ name: string;
6
+ header: string;
7
+ script: string;
8
+ /** Whether the package backend serves `root.output` for this op; helper ops report through the helper instead. */
9
+ output: boolean;
10
+ }
11
+ /**
12
+ * `createRootAccess(options)` → `{ state, authorize, run, remove }`, plain
13
+ * ES5 for DSM's desktop. Every DSM call goes through `options.send` (the
14
+ * AppWindow's sendWebAPI) as the signed-in administrator:
15
+ *
16
+ * - authorize: DSM's own password confirmation, then one disabled root task
17
+ * with exactly the embedded script. The one-use token goes into that single
18
+ * create call and is never kept.
19
+ * - run: re-reads the task and runs it only if it is still exactly ours (the
20
+ * first run after an authorize uses the task that authorize just read back), then
21
+ * waits for its history entry and asks the backend for the output. A queued
22
+ * or running task keeps the wait going, up to RUN_LIMIT_MS (loaded NAS took
23
+ * 4.5 minutes), and `options.progress({op, state, elapsedMs})` hears each poll. Repair
24
+ * additionally requires fresh PasswordConfirm and another exact task check.
25
+ * - reads follow spec/scheduler/v1: a step lists Task Scheduler once and gets
26
+ * the task by that id; a step that deletes nothing gets the id an earlier
27
+ * list showed and lists again when DSM answers 4801 or another task. A
28
+ * duplicate name and any difference from the exact definition and script
29
+ * are never ready.
30
+ * - an older version of our task is "outdated" and never runs; authorizing
31
+ * again replaces it. A same-named task that is not ours is a "conflict" and
32
+ * is never run, replaced or deleted.
33
+ */
34
+ export declare const ROOT_RUNTIME: string;
@@ -0,0 +1,2 @@
1
+ export { ROOT_RUNTIME, type RootTask } from './native/root-runtime';
2
+ export { AUTHORIZATION_RUNTIME } from './native/authorization-runtime';
@@ -78,6 +78,12 @@ export declare const protocolCodes: {
78
78
  readonly retryable: true;
79
79
  readonly httpStatus: 503;
80
80
  };
81
+ /** The executor is running the App's start step after an install or upgrade; status answers state starting until it ends. */
82
+ readonly EXECUTOR_STARTING: {
83
+ readonly kind: "refusal";
84
+ readonly retryable: true;
85
+ readonly httpStatus: 503;
86
+ };
81
87
  /** The executor could not read or write its protected state. */
82
88
  readonly STORAGE_ERROR: {
83
89
  readonly kind: "refusal";
@@ -368,7 +374,7 @@ export declare const protocolCodes: {
368
374
  };
369
375
  };
370
376
  export type ProtocolCode = keyof typeof protocolCodes;
371
- export type RefusalCode = "AUTH_DENIED" | "INELIGIBLE" | "APP_DENIED" | "ADMIN_REQUIRED" | "DELEGATION_DENIED" | "SCOPE_DENIED" | "POLICY_DENIED" | "PEER_DENIED" | "PERMISSION_DENIED" | "UNKNOWN_OP" | "INVALID_REQUEST" | "REQUEST_TOO_LARGE" | "EXECUTOR_PAUSED" | "STORAGE_ERROR" | "INTERNAL" | "WRITE_FAILED" | "READ_FAILED" | "DSM_FAILED" | "ROOT_FAILED" | "ROOT_TIMEOUT" | "ROOT_BUSY" | "ROOT_STAGING_FULL" | "ROOT_JOB_NOT_FOUND" | "PORTAL_FAILED" | "NO_SPACE" | "SCOPE_APPROVAL_STALE" | "IDENTITY_CHANGED" | "needs-scope-confirmation" | "disabled" | "invalid-destination" | "invalid-size" | "operation-conflict" | "operation-not-found" | "destination-exists" | "invalid-path" | "path-too-deep" | "destination-not-directory" | "name-too-long" | "not-found" | "not-a-file" | "recursive-required" | "recycle-bin-disabled" | "task-not-found" | "too-many-tasks" | "queue-full" | "limit-exceeded";
377
+ export type RefusalCode = "AUTH_DENIED" | "INELIGIBLE" | "APP_DENIED" | "ADMIN_REQUIRED" | "DELEGATION_DENIED" | "SCOPE_DENIED" | "POLICY_DENIED" | "PEER_DENIED" | "PERMISSION_DENIED" | "UNKNOWN_OP" | "INVALID_REQUEST" | "REQUEST_TOO_LARGE" | "EXECUTOR_PAUSED" | "EXECUTOR_STARTING" | "STORAGE_ERROR" | "INTERNAL" | "WRITE_FAILED" | "READ_FAILED" | "DSM_FAILED" | "ROOT_FAILED" | "ROOT_TIMEOUT" | "ROOT_BUSY" | "ROOT_STAGING_FULL" | "ROOT_JOB_NOT_FOUND" | "PORTAL_FAILED" | "NO_SPACE" | "SCOPE_APPROVAL_STALE" | "IDENTITY_CHANGED" | "needs-scope-confirmation" | "disabled" | "invalid-destination" | "invalid-size" | "operation-conflict" | "operation-not-found" | "destination-exists" | "invalid-path" | "path-too-deep" | "destination-not-directory" | "name-too-long" | "not-found" | "not-a-file" | "recursive-required" | "recycle-bin-disabled" | "task-not-found" | "too-many-tasks" | "queue-full" | "limit-exceeded";
372
378
  export type OutcomeCode = "OPERATION_CANCELED" | "CANCEL_REQUESTED" | "CLEANUP_PENDING";
373
379
  export type ReasonCode = "grant-revoked" | "destination-replaced" | "integration-disabled" | "validation-denied" | "scope-changed" | "storage-error" | "operation-canceled-by-user" | "operation-deadline-exceeded";
374
380
  export type ClientCode = "EXECUTOR_UNAVAILABLE" | "EXECUTOR_TIMEOUT" | "EXECUTOR_TOO_LARGE" | "EXECUTOR_PROTOCOL";
@@ -0,0 +1,13 @@
1
+ declare var __VLS_7: {};
2
+ type __VLS_Slots = {} & {
3
+ default?: (props: typeof __VLS_7) => any;
4
+ };
5
+ declare const __VLS_base: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
6
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
7
+ declare const _default: typeof __VLS_export;
8
+ export default _default;
9
+ type __VLS_WithSlots<T, S> = T & {
10
+ new (): {
11
+ $slots: S;
12
+ };
13
+ };
@@ -14,6 +14,8 @@ export interface AppShellPage {
14
14
  component?: Component;
15
15
  /** Reachable through v-model but not listed in the sidebar. */
16
16
  hidden?: boolean;
17
+ /** 'bottom': listed after every other page, in a group of its own (an App's settings). */
18
+ placement?: 'bottom';
17
19
  /** Replaces the shell's description for this page. */
18
20
  description?: string;
19
21
  /** false: the page draws its own header. */
@@ -0,0 +1,3 @@
1
+ import type { InjectionKey, ShallowRef } from 'vue';
2
+ /** Where AppShell's page header takes a page's own actions. */
3
+ export declare const PageActionsTarget: InjectionKey<Readonly<ShallowRef<HTMLElement | null>>>;
package/dist/src/vue.d.ts CHANGED
@@ -3,6 +3,7 @@ export { ExecutorSetupKey, useExecutorSetup } from './delegate/use-executor-setu
3
3
  export { createSession, type IdentitySession, type SessionSubject } from './identity/session';
4
4
  export { useNasRequest } from './nas/use-request';
5
5
  export { default as AppShell } from './shell/AppShell.vue';
6
+ export { default as PageActions } from './shell/PageActions.vue';
6
7
  export type { AppShellDenied, AppShellPage, AppShellPageEntry } from './shell/app-pages';
7
8
  export { default as FilesPage } from './files/FilesPage.vue';
8
9
  export { default as FileBrowser } from './files/FileBrowser.vue';
@@ -15,6 +16,7 @@ export { default as ExecutorApproval } from './delegate/ExecutorApproval.vue';
15
16
  export { default as ExecutorNotice } from './delegate/ExecutorNotice.vue';
16
17
  export { default as DelegatePanel } from './delegate/DelegatePanel.vue';
17
18
  export { default as BackgroundSavePanel } from './delegate/BackgroundSavePanel.vue';
19
+ export { default as BackgroundSaveSettings } from './delegate/BackgroundSaveSettings.vue';
18
20
  export { default as AuthorizationGate } from './authorization/AuthorizationGate.vue';
19
21
  export { useAuthorization, type AuthorizationControl, type AuthorizationGateState } from './authorization/use-authorization';
20
22
  export { default as AuthorizationSettings } from './authorization/AuthorizationSettings.vue';
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- .executor-help[data-v-928609ab]{margin:0 0 var(--ui-space-3,12px);max-width:72ch;color:var(--ui-text-secondary)}.executor-summary[data-v-928609ab]{margin-bottom:var(--ui-space-3,12px)}.executor-form[data-v-928609ab]{margin-top:var(--ui-space-4,16px);max-width:28rem}.executor-hint[data-v-928609ab]{font-size:12px;color:var(--ui-text-secondary)}.executor-reason[data-v-928609ab]{display:block;margin-top:var(--ui-space-1,4px);font-size:12px}.executor-alert[data-v-928609ab]{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:var(--ui-space-2,8px)}.executor-notice[data-v-771da19a]{margin-bottom:var(--ui-space-4, 16px)}.executor-notice-body[data-v-771da19a]{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:var(--ui-space-2, 8px)}.app-shell[data-v-098c9e72]{height:100%;min-width:0;grid-template-rows:minmax(0,1fr)}.app-shell[data-v-098c9e72]>div{min-height:0}.app-shell[data-v-098c9e72] main{display:flex;flex-direction:column;overflow:hidden}.app-page[data-v-098c9e72]{flex:1 1 auto;min-height:0;overflow-y:auto}.app-denied[data-v-098c9e72]{height:100%;overflow-y:auto}.app-shell-fill[data-v-098c9e72]{max-height:100dvh}.app-page-fill[data-v-098c9e72]{display:flex;flex-direction:column;overflow:hidden}.app-page-fill[data-v-098c9e72]>[data-page-content-body]{display:flex;flex:1 1 auto;flex-direction:column;width:100%;min-height:0}.app-page-fill .app-notices[data-v-098c9e72]{flex:0 0 auto}.app-page-fill .app-page-content[data-v-098c9e72]{display:grid;flex:1 1 auto;grid-template-columns:minmax(0,1fr);grid-template-rows:minmax(0,1fr);min-height:0}.app-notices[data-v-098c9e72]{display:flex;flex-direction:column;gap:var(--ui-space-2, 8px);margin-bottom:var(--ui-space-4, 16px)}.app-page-content[data-v-098c9e72]{padding-bottom:var(--ui-space-6, 24px)}.file-browser[data-v-c689761c]{min-width:0;color:var(--ui-text)}.file-toolbar[data-v-c689761c]{display:flex;flex-wrap:wrap;gap:var(--ui-space-2, 8px);margin-block:var(--ui-space-3, 12px)}.file-location[data-v-c689761c]{flex-wrap:nowrap;align-items:center;gap:var(--ui-space-1, 4px)}.file-path[data-v-c689761c]{flex:1;min-width:0;margin-inline-start:var(--ui-space-2, 8px)}.file-columns[data-v-c689761c]{display:grid;grid-template-columns:minmax(140px,1fr) minmax(0,3fr);gap:var(--ui-space-3, 12px);height:clamp(240px,60vh,400px)}.file-tree[data-v-c689761c]{min-width:0;overflow:auto;border-inline-end:1px solid var(--ui-border)}.file-content[data-v-c689761c]{display:flex;flex-direction:column;min-width:0;min-height:0;overflow:auto}.file-empty[data-v-c689761c]{display:flex;flex-direction:column;align-items:center;gap:var(--ui-space-2, 8px);padding-block:var(--ui-space-6, 24px);color:var(--ui-text-muted)}.file-name[data-v-c689761c]{display:inline-flex;align-items:center;gap:var(--ui-space-2, 8px);overflow-wrap:anywhere}.file-bytes[data-v-c689761c]{font-variant-numeric:tabular-nums}.file-selection[data-v-c689761c]{overflow-wrap:anywhere}@media(max-width:600px){.file-columns[data-v-c689761c]{grid-template-columns:minmax(0,1fr);height:auto}.file-content[data-v-c689761c] th:nth-child(2),.file-content[data-v-c689761c] td:nth-child(2),.file-content[data-v-c689761c] th:nth-child(3),.file-content[data-v-c689761c] td:nth-child(3){display:none}.file-tree[data-v-c689761c]{height:clamp(96px,25vh,180px);border-inline-end:0;border-bottom:1px solid var(--ui-border)}.file-content[data-v-c689761c]{height:clamp(200px,45vh,360px)}}.nas-picker-content[data-v-6ed8b8f6]{max-height:65vh;overflow:auto}.save-message[data-v-6ed8b8f6]{--ui-text-secondary:var(--ui-text)}.save-consent[data-v-6ed8b8f6]{color:var(--ui-text);margin-block:0 var(--ui-space-4,16px)}.files-actions[data-v-15f9eb8e]{display:flex;flex-wrap:wrap;gap:var(--ui-space-2, 8px)}.files-path[data-v-15f9eb8e]{display:flex;min-width:0}.identity-login[data-v-1c0358cd]{max-width:36rem;margin-inline:auto;padding:var(--ui-space-4, 16px);overflow:auto;max-height:100%;color:var(--ui-text);font-family:var(--ui-font-sans);font-size:13px;line-height:1.5}.identity-login p[data-v-1c0358cd]{margin-block:var(--ui-space-4, 16px);overflow-wrap:anywhere}.bg-cards[data-v-fa2b6101]{display:grid;gap:var(--ui-space-3,12px);min-width:0;overflow-wrap:anywhere}.bg-card-body[data-v-fa2b6101]{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ui-space-2,8px);min-width:0}.bg-card-body>span[data-v-fa2b6101]{min-width:0;max-width:100%}.integration-actions[data-v-fa2b6101]{display:flex;flex-wrap:wrap;gap:var(--ui-space-2,8px)}.bg-schedules[data-v-fa2b6101]{margin-block-start:var(--ui-space-6,24px);min-width:0;overflow-wrap:anywhere}.bg-schedules p[data-v-fa2b6101]{min-width:0;max-width:100%}.bg-schedules h3[data-v-fa2b6101]{font-size:15px;font-weight:600}.bg-schedule-form[data-v-fa2b6101]{margin-block:var(--ui-space-4,16px)}.bg-path[data-v-fa2b6101]{display:flex;align-items:center;gap:var(--ui-space-2,8px);min-width:0;max-width:100%}.executor-approval[data-v-632b6fba]{padding:var(--ui-space-6, 24px)}.executor-brand[data-v-632b6fba]{display:flex;align-items:center;gap:var(--ui-space-2, 8px);margin-bottom:var(--ui-space-4, 16px);font-size:16px;font-weight:600;color:var(--ui-text-primary)}.executor-brand img[data-v-632b6fba]{width:24px;height:24px}.delegate-panel[data-v-c590f505]{min-width:0;overflow-wrap:anywhere}h3[data-v-c590f505]{font-size:var(--ui-font-size-base,14px);font-weight:600;margin:var(--ui-space-6,24px) 0 var(--ui-space-3,12px)}.records[data-v-c590f505]{list-style:none;padding:0;margin:0}.records li[data-v-c590f505]{display:flex;align-items:flex-start;justify-content:space-between;flex-wrap:wrap;gap:var(--ui-space-3,12px);padding-block:var(--ui-space-4,16px);border-bottom:1px solid var(--ui-border)}.records li>div[data-v-c590f505],.records li>span[data-v-c590f505],.destination[data-v-c590f505]{min-width:0;max-width:100%;overflow-wrap:anywhere}.records p[data-v-c590f505]{margin:var(--ui-space-2,8px) 0 0}.destination[data-v-c590f505]{display:flex;align-items:center;gap:var(--ui-space-2,8px)}.background-save-panel[data-v-5ef5e256]{min-width:0;overflow-wrap:anywhere}.save-message[data-v-5ef5e256]{--ui-text-secondary:var(--ui-text)}.save-help[data-v-5ef5e256]{margin:0 0 var(--ui-space-3,12px);max-width:72ch;color:var(--ui-text-secondary)}.save-summary[data-v-5ef5e256]{margin-bottom:var(--ui-space-3,12px)}h3[data-v-5ef5e256]{font-size:var(--ui-font-size-base,14px);font-weight:600;margin:var(--ui-space-6,24px) 0 var(--ui-space-3,12px)}.save-actions[data-v-5ef5e256],.save-records li[data-v-5ef5e256],.save-danger[data-v-5ef5e256]{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:var(--ui-space-2,8px)}.save-actions[data-v-5ef5e256]{justify-content:flex-start;margin-top:var(--ui-space-3,12px)}.save-records[data-v-5ef5e256]{list-style:none;margin:0;padding:0}.save-records li[data-v-5ef5e256]{padding-block:var(--ui-space-2,8px);border-bottom:1px solid var(--ui-border)}.save-record[data-v-5ef5e256]{display:flex;flex-direction:column;align-items:flex-start;min-width:0;flex:1}.save-name[data-v-5ef5e256]{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.save-note[data-v-5ef5e256]{margin:var(--ui-space-1,4px) 0 0;font-size:12px;color:var(--ui-text-secondary);white-space:normal}.save-alert[data-v-5ef5e256]{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:var(--ui-space-2,8px)}.save-icon[data-v-5ef5e256]{width:16px;height:16px}[data-save-operations][data-v-5ef5e256] table{table-layout:fixed}[data-save-operations][data-v-5ef5e256] th,[data-save-operations][data-v-5ef5e256] td{overflow-wrap:normal;white-space:nowrap}[data-save-operations][data-v-5ef5e256] td{padding-block:var(--ui-space-2,8px)}.save-example[data-v-5ef5e256]{margin-top:var(--ui-space-5,20px)}.save-pages[data-v-5ef5e256]{margin-top:var(--ui-space-3,12px)}.save-danger[data-v-5ef5e256]{flex:1;margin-top:var(--ui-space-2,8px);padding-top:var(--ui-space-4,16px);border-top:1px solid var(--ui-border)}.save-danger p[data-v-5ef5e256]{margin:0;flex:1 1 20rem;max-width:72ch;color:var(--ui-text-secondary)}.authorization-view[data-v-e16b5f7d]{display:flex;flex-direction:column;gap:12px}.authorization-body[data-v-e16b5f7d]{margin:0;font-size:13px;line-height:1.6;color:var(--ui-text);text-wrap:pretty}.authorization-status[data-v-e16b5f7d],.authorization-failed[data-v-e16b5f7d]{color:var(--ui-text)}.authorization-content[data-v-e16b5f7d]{display:flex;flex-direction:column;height:100%;min-height:0}.authorization-content[data-v-e16b5f7d] .app-shell{flex:1;min-height:0;height:auto}.authorization-setting[data-v-f031e7c7]{display:flex;align-items:center;flex-wrap:wrap;gap:12px}.authorization-revoke-body[data-v-f031e7c7]{margin:0;font-size:13px;line-height:1.6;color:var(--ui-text)}.authorization-state[data-v-f031e7c7]{display:inline-flex;align-items:center;gap:6px;color:var(--ui-text)}
1
+ .executor-help[data-v-ef449050]{margin:0 0 var(--ui-space-3,12px);max-width:72ch;color:var(--ui-text-secondary)}.executor-summary[data-v-ef449050]:not(:last-child){margin-bottom:var(--ui-space-3,12px)}.executor-form[data-v-ef449050]{margin-top:var(--ui-space-4,16px);max-width:28rem}.executor-hint[data-v-ef449050]{font-size:12px;color:var(--ui-text-secondary)}.executor-reason[data-v-ef449050]{display:block;margin-top:var(--ui-space-1,4px);font-size:12px}.executor-alert[data-v-ef449050]{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:var(--ui-space-2,8px)}.executor-notice[data-v-949f744b]{margin-bottom:var(--ui-space-4, 16px)}.executor-notice-body[data-v-949f744b]{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:var(--ui-space-2, 8px)}.app-shell[data-v-32986d03]{height:100%;min-width:0;grid-template-rows:minmax(0,1fr)}.app-shell[data-v-32986d03]>div{min-height:0}.app-shell[data-v-32986d03] main{display:flex;flex-direction:column;overflow:hidden}.app-page[data-v-32986d03]{flex:1 1 auto;min-height:0;overflow-y:auto}.app-denied[data-v-32986d03]{height:100%;overflow-y:auto}.app-page-actions[data-v-32986d03]{display:contents}.app-shell-fill[data-v-32986d03]{max-height:100dvh}.app-page-fill[data-v-32986d03]{display:flex;flex-direction:column;overflow:hidden}.app-page-fill[data-v-32986d03]>[data-page-content-body]{display:flex;flex:1 1 auto;flex-direction:column;width:100%;min-height:0}.app-page-fill .app-notices[data-v-32986d03]{flex:0 0 auto}.app-page-fill .app-page-content[data-v-32986d03]{display:grid;flex:1 1 auto;grid-template-columns:minmax(0,1fr);grid-template-rows:minmax(0,1fr);min-height:0}.app-notices[data-v-32986d03]{display:flex;flex-direction:column;gap:var(--ui-space-2, 8px);margin-bottom:var(--ui-space-4, 16px)}.app-page-content[data-v-32986d03]{padding-bottom:var(--ui-space-6, 24px)}.file-browser[data-v-c689761c]{min-width:0;color:var(--ui-text)}.file-toolbar[data-v-c689761c]{display:flex;flex-wrap:wrap;gap:var(--ui-space-2, 8px);margin-block:var(--ui-space-3, 12px)}.file-location[data-v-c689761c]{flex-wrap:nowrap;align-items:center;gap:var(--ui-space-1, 4px)}.file-path[data-v-c689761c]{flex:1;min-width:0;margin-inline-start:var(--ui-space-2, 8px)}.file-columns[data-v-c689761c]{display:grid;grid-template-columns:minmax(140px,1fr) minmax(0,3fr);gap:var(--ui-space-3, 12px);height:clamp(240px,60vh,400px)}.file-tree[data-v-c689761c]{min-width:0;overflow:auto;border-inline-end:1px solid var(--ui-border)}.file-content[data-v-c689761c]{display:flex;flex-direction:column;min-width:0;min-height:0;overflow:auto}.file-empty[data-v-c689761c]{display:flex;flex-direction:column;align-items:center;gap:var(--ui-space-2, 8px);padding-block:var(--ui-space-6, 24px);color:var(--ui-text-muted)}.file-name[data-v-c689761c]{display:inline-flex;align-items:center;gap:var(--ui-space-2, 8px);overflow-wrap:anywhere}.file-bytes[data-v-c689761c]{font-variant-numeric:tabular-nums}.file-selection[data-v-c689761c]{overflow-wrap:anywhere}@media(max-width:600px){.file-columns[data-v-c689761c]{grid-template-columns:minmax(0,1fr);height:auto}.file-content[data-v-c689761c] th:nth-child(2),.file-content[data-v-c689761c] td:nth-child(2),.file-content[data-v-c689761c] th:nth-child(3),.file-content[data-v-c689761c] td:nth-child(3){display:none}.file-tree[data-v-c689761c]{height:clamp(96px,25vh,180px);border-inline-end:0;border-bottom:1px solid var(--ui-border)}.file-content[data-v-c689761c]{height:clamp(200px,45vh,360px)}}.nas-picker-content[data-v-6ed8b8f6]{max-height:65vh;overflow:auto}.save-message[data-v-6ed8b8f6]{--ui-text-secondary:var(--ui-text)}.save-consent[data-v-6ed8b8f6]{color:var(--ui-text);margin-block:0 var(--ui-space-4,16px)}.files-actions[data-v-15f9eb8e]{display:flex;flex-wrap:wrap;gap:var(--ui-space-2, 8px)}.files-path[data-v-15f9eb8e]{display:flex;min-width:0}.identity-login[data-v-1c0358cd]{max-width:36rem;margin-inline:auto;padding:var(--ui-space-4, 16px);overflow:auto;max-height:100%;color:var(--ui-text);font-family:var(--ui-font-sans);font-size:13px;line-height:1.5}.identity-login p[data-v-1c0358cd]{margin-block:var(--ui-space-4, 16px);overflow-wrap:anywhere}.bg-cards[data-v-3e23f18f]{display:grid;gap:var(--ui-space-3,12px);min-width:0;overflow-wrap:anywhere}.bg-card-body[data-v-3e23f18f]{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ui-space-2,8px);min-width:0}.bg-card-body>span[data-v-3e23f18f]{min-width:0;max-width:100%}.integration-actions[data-v-3e23f18f]{display:flex;flex-wrap:wrap;gap:var(--ui-space-2,8px)}.bg-schedules[data-v-3e23f18f]{margin-block-start:var(--ui-space-6,24px);min-width:0;overflow-wrap:anywhere}.bg-schedules p[data-v-3e23f18f]{min-width:0;max-width:100%}.bg-schedule-form[data-v-3e23f18f]{margin-block:var(--ui-space-4,16px)}.bg-path[data-v-3e23f18f]{display:flex;align-items:center;gap:var(--ui-space-2,8px);min-width:0;max-width:100%}.executor-approval[data-v-88a4ee77]{padding:var(--ui-space-6, 24px)}.executor-brand[data-v-88a4ee77]{display:flex;align-items:center;gap:var(--ui-space-2, 8px);margin-bottom:var(--ui-space-4, 16px);font-size:16px;font-weight:600;color:var(--ui-text-primary)}.executor-brand img[data-v-88a4ee77]{width:24px;height:24px}.delegate-panel[data-v-e6f168a0]{min-width:0;overflow-wrap:anywhere}.delegate-group[data-v-e6f168a0]{margin-top:var(--ui-space-6,24px)}.records[data-v-e6f168a0]{list-style:none;padding:0;margin:0}.records li[data-v-e6f168a0]{display:flex;align-items:flex-start;justify-content:space-between;flex-wrap:wrap;gap:var(--ui-space-3,12px);padding-block:var(--ui-space-4,16px);border-bottom:1px solid var(--ui-border)}.records li>div[data-v-e6f168a0],.records li>span[data-v-e6f168a0],.destination[data-v-e6f168a0]{min-width:0;max-width:100%;overflow-wrap:anywhere}.records p[data-v-e6f168a0]{margin:var(--ui-space-2,8px) 0 0}.destination[data-v-e6f168a0]{display:flex;align-items:center;gap:var(--ui-space-2,8px)}.background-save-settings[data-v-b77823f5]{min-width:0;overflow-wrap:anywhere}.save-help[data-v-b77823f5]{margin:0 0 var(--ui-space-2,8px);max-width:72ch;color:var(--ui-text-secondary)}.save-form[data-v-b77823f5]{max-width:44rem}.save-actions[data-v-b77823f5],.save-alert[data-v-b77823f5],.save-danger[data-v-b77823f5]{display:flex;align-items:center;flex-wrap:wrap;gap:var(--ui-space-2,8px)}.save-alert[data-v-b77823f5],.save-danger[data-v-b77823f5]{justify-content:space-between}.save-none[data-v-b77823f5]{color:var(--ui-text-secondary)}.save-reason[data-v-b77823f5]{display:block;margin-top:var(--ui-space-1,4px);font-size:12px}.save-danger[data-v-b77823f5]{flex:1;padding-top:var(--ui-space-3,12px);border-top:1px solid var(--ui-border)}.save-danger p[data-v-b77823f5]{margin:0;flex:1 1 20rem;max-width:72ch;font-size:12px;color:var(--ui-text-secondary)}.background-save-panel[data-v-3cbedd4f]{min-width:0;overflow-wrap:anywhere}.save-help[data-v-3cbedd4f]{margin:0 0 var(--ui-space-3,12px);max-width:72ch;color:var(--ui-text-secondary)}.save-group[data-v-3cbedd4f]{margin-top:var(--ui-space-6,24px)}.save-actions[data-v-3cbedd4f],.save-alert[data-v-3cbedd4f]{display:flex;align-items:center;flex-wrap:wrap;gap:var(--ui-space-2,8px)}.save-alert[data-v-3cbedd4f]{justify-content:space-between}.save-actions[data-v-3cbedd4f]{margin-bottom:var(--ui-space-3,12px)}.save-name[data-v-3cbedd4f]{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.save-note[data-v-3cbedd4f]{margin:var(--ui-space-1,4px) 0 0;font-size:12px;color:var(--ui-text-secondary);white-space:normal}.save-icon[data-v-3cbedd4f]{width:16px;height:16px}[data-save-operations][data-v-3cbedd4f] table{table-layout:fixed}[data-save-operations][data-v-3cbedd4f] th,[data-save-operations][data-v-3cbedd4f] td{overflow-wrap:normal;white-space:nowrap}[data-save-operations][data-v-3cbedd4f] td{padding-block:var(--ui-space-2,8px)}.save-pages[data-v-3cbedd4f]{margin-top:var(--ui-space-3,12px)}.authorization-view[data-v-e16b5f7d]{display:flex;flex-direction:column;gap:12px}.authorization-body[data-v-e16b5f7d]{margin:0;font-size:13px;line-height:1.6;color:var(--ui-text);text-wrap:pretty}.authorization-status[data-v-e16b5f7d],.authorization-failed[data-v-e16b5f7d]{color:var(--ui-text)}.authorization-content[data-v-e16b5f7d]{display:flex;flex-direction:column;height:100%;min-height:0}.authorization-content[data-v-e16b5f7d] .app-shell{flex:1;min-height:0;height:auto}.authorization-setting[data-v-f031e7c7]{display:flex;align-items:center;flex-wrap:wrap;gap:12px}.authorization-revoke-body[data-v-f031e7c7]{margin:0;font-size:13px;line-height:1.6;color:var(--ui-text)}.authorization-state[data-v-f031e7c7]{display:inline-flex;align-items:center;gap:6px;color:var(--ui-text)}