@lumenkey/cli 0.3.0 → 0.4.0-rc.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.
Files changed (184) hide show
  1. package/README.md +51 -2
  2. package/dist/cli/copied.js +86 -85
  3. package/dist/cli/index.js +56 -44
  4. package/dist/cli/render.js +5 -1
  5. package/dist/core/asset-stream.d.ts +16 -0
  6. package/dist/core/asset-stream.js +64 -0
  7. package/dist/core/atomic-config-file.js +8 -7
  8. package/dist/core/chinese-messages.d.ts +4 -0
  9. package/dist/core/chinese-messages.js +907 -0
  10. package/dist/core/chinese-script.d.ts +7 -0
  11. package/dist/core/chinese-script.js +28 -0
  12. package/dist/core/client.js +2 -1
  13. package/dist/core/config-dir.js +2 -1
  14. package/dist/core/config.js +7 -6
  15. package/dist/core/download-root.d.ts +5 -0
  16. package/dist/core/download-root.js +64 -0
  17. package/dist/core/download.js +15 -12
  18. package/dist/core/generation-input.js +3 -2
  19. package/dist/core/generation.d.ts +8 -1
  20. package/dist/core/generation.js +13 -10
  21. package/dist/core/job-display.js +7 -6
  22. package/dist/core/locale.d.ts +2 -0
  23. package/dist/core/locale.js +172 -142
  24. package/dist/core/outcome.d.ts +6 -0
  25. package/dist/core/outcome.js +17 -4
  26. package/dist/core/output-path.d.ts +3 -1
  27. package/dist/core/output-path.js +5 -2
  28. package/dist/core/params.js +26 -25
  29. package/dist/core/profiles.js +5 -4
  30. package/dist/core/set-values.d.ts +0 -1
  31. package/dist/core/set-values.js +7 -7
  32. package/dist/core/submission-journal.js +43 -17
  33. package/dist/core/version.js +2 -3
  34. package/dist/mcp/server.js +30 -29
  35. package/dist/studio/asset-integrity-hash.d.ts +28 -0
  36. package/dist/studio/asset-integrity-hash.js +93 -0
  37. package/dist/studio/asset-integrity-queue.d.ts +24 -0
  38. package/dist/studio/asset-integrity-queue.js +94 -0
  39. package/dist/studio/asset-store.d.ts +52 -0
  40. package/dist/studio/asset-store.js +352 -0
  41. package/dist/studio/canvas/LICENSES.txt +1590 -0
  42. package/dist/studio/canvas/dependencies.json +862 -0
  43. package/dist/studio/canvas/director-source-manifest.json +47 -0
  44. package/dist/studio/canvas/editor.css +239 -0
  45. package/dist/studio/canvas/editor.js +4613 -0
  46. package/dist/studio/canvas/integration-source-manifest.json +384 -0
  47. package/dist/studio/canvas/source-manifest.json +240 -0
  48. package/dist/studio/canvas-store.d.ts +1254 -0
  49. package/dist/studio/canvas-store.js +205 -0
  50. package/dist/studio/capture-placement.d.ts +11 -0
  51. package/dist/studio/capture-placement.js +85 -0
  52. package/dist/studio/cloud-contract.d.ts +128 -0
  53. package/dist/studio/cloud-contract.js +229 -0
  54. package/dist/studio/cloud-service.d.ts +178 -0
  55. package/dist/studio/cloud-service.js +202 -0
  56. package/dist/studio/director-captures.d.ts +59 -0
  57. package/dist/studio/director-captures.js +141 -0
  58. package/dist/studio/director-contract.d.ts +1489 -0
  59. package/dist/studio/director-contract.js +288 -0
  60. package/dist/studio/director-png.d.ts +6 -0
  61. package/dist/studio/director-png.js +41 -0
  62. package/dist/studio/director-relations.d.ts +40 -0
  63. package/dist/studio/director-relations.js +103 -0
  64. package/dist/studio/document-authority.d.ts +7 -0
  65. package/dist/studio/document-authority.js +50 -0
  66. package/dist/studio/draft-store.d.ts +95 -0
  67. package/dist/studio/draft-store.js +100 -0
  68. package/dist/studio/errors.d.ts +85 -0
  69. package/dist/studio/errors.js +94 -0
  70. package/dist/studio/launch.d.ts +5 -0
  71. package/dist/studio/launch.js +31 -0
  72. package/dist/studio/media.d.ts +9 -0
  73. package/dist/studio/media.js +50 -0
  74. package/dist/studio/output-save-contract.d.ts +1321 -0
  75. package/dist/studio/output-save-contract.js +26 -0
  76. package/dist/studio/output-save-journal.d.ts +971 -0
  77. package/dist/studio/output-save-journal.js +287 -0
  78. package/dist/studio/output-save-recovery.d.ts +18 -0
  79. package/dist/studio/output-save-recovery.js +161 -0
  80. package/dist/studio/output-save-service.d.ts +436 -0
  81. package/dist/studio/output-save-service.js +251 -0
  82. package/dist/studio/output-save-worker.d.ts +40 -0
  83. package/dist/studio/output-save-worker.js +360 -0
  84. package/dist/studio/paths.d.ts +6 -0
  85. package/dist/studio/paths.js +68 -0
  86. package/dist/studio/run-journal.d.ts +993 -0
  87. package/dist/studio/run-journal.js +125 -0
  88. package/dist/studio/server.d.ts +17 -0
  89. package/dist/studio/server.js +440 -0
  90. package/dist/studio/session.d.ts +6 -0
  91. package/dist/studio/session.js +26 -0
  92. package/dist/studio/shell.d.ts +3 -0
  93. package/dist/studio/shell.js +23 -0
  94. package/dist/studio/style.d.ts +2 -0
  95. package/dist/studio/style.js +29 -0
  96. package/dist/studio/types.d.ts +26 -0
  97. package/dist/studio/types.js +2 -0
  98. package/dist/studio/web/app.d.ts +2 -0
  99. package/dist/studio/web/app.js +662 -0
  100. package/dist/studio/web/asset-controller.d.ts +37 -0
  101. package/dist/studio/web/asset-controller.js +191 -0
  102. package/dist/studio/web/asset-model.d.ts +29 -0
  103. package/dist/studio/web/asset-model.js +51 -0
  104. package/dist/studio/web/controller.d.ts +113 -0
  105. package/dist/studio/web/controller.js +401 -0
  106. package/dist/studio/web/messages.d.ts +2 -0
  107. package/dist/studio/web/messages.js +74 -0
  108. package/dist/studio/web/model.d.ts +75 -0
  109. package/dist/studio/web/model.js +182 -0
  110. package/dist/studio/web/save-controller.d.ts +85 -0
  111. package/dist/studio/web/save-controller.js +495 -0
  112. package/dist/studio/web/save-model.d.ts +63 -0
  113. package/dist/studio/web/save-model.js +64 -0
  114. package/dist/studio/web/save-queue.d.ts +7 -0
  115. package/dist/studio/web/save-queue.js +62 -0
  116. package/dist/studio/web/save-view.d.ts +9 -0
  117. package/dist/studio/web/save-view.js +19 -0
  118. package/dist/studio/writer-lock.d.ts +5 -0
  119. package/dist/studio/writer-lock.js +88 -0
  120. package/package.json +11 -5
  121. package/dist/cli/copied.d.ts.map +0 -1
  122. package/dist/cli/copied.js.map +0 -1
  123. package/dist/cli/index.d.ts.map +0 -1
  124. package/dist/cli/index.js.map +0 -1
  125. package/dist/cli/render.d.ts.map +0 -1
  126. package/dist/cli/render.js.map +0 -1
  127. package/dist/core/atomic-config-file.d.ts.map +0 -1
  128. package/dist/core/atomic-config-file.js.map +0 -1
  129. package/dist/core/chat.d.ts.map +0 -1
  130. package/dist/core/chat.js.map +0 -1
  131. package/dist/core/client.d.ts.map +0 -1
  132. package/dist/core/client.js.map +0 -1
  133. package/dist/core/config-dir.d.ts.map +0 -1
  134. package/dist/core/config-dir.js.map +0 -1
  135. package/dist/core/config-error.d.ts.map +0 -1
  136. package/dist/core/config-error.js.map +0 -1
  137. package/dist/core/config.d.ts.map +0 -1
  138. package/dist/core/config.js.map +0 -1
  139. package/dist/core/credit-cap.d.ts.map +0 -1
  140. package/dist/core/credit-cap.js.map +0 -1
  141. package/dist/core/download.d.ts.map +0 -1
  142. package/dist/core/download.js.map +0 -1
  143. package/dist/core/error-result.d.ts.map +0 -1
  144. package/dist/core/error-result.js.map +0 -1
  145. package/dist/core/explain.d.ts.map +0 -1
  146. package/dist/core/explain.js.map +0 -1
  147. package/dist/core/generation-input.d.ts.map +0 -1
  148. package/dist/core/generation-input.js.map +0 -1
  149. package/dist/core/generation-result.d.ts.map +0 -1
  150. package/dist/core/generation-result.js.map +0 -1
  151. package/dist/core/generation.d.ts.map +0 -1
  152. package/dist/core/generation.js.map +0 -1
  153. package/dist/core/job-display.d.ts.map +0 -1
  154. package/dist/core/job-display.js.map +0 -1
  155. package/dist/core/locale.d.ts.map +0 -1
  156. package/dist/core/locale.js.map +0 -1
  157. package/dist/core/origin.d.ts.map +0 -1
  158. package/dist/core/origin.js.map +0 -1
  159. package/dist/core/outcome.d.ts.map +0 -1
  160. package/dist/core/outcome.js.map +0 -1
  161. package/dist/core/output-path.d.ts.map +0 -1
  162. package/dist/core/output-path.js.map +0 -1
  163. package/dist/core/params.d.ts.map +0 -1
  164. package/dist/core/params.js.map +0 -1
  165. package/dist/core/poller.d.ts.map +0 -1
  166. package/dist/core/poller.js.map +0 -1
  167. package/dist/core/profiles.d.ts.map +0 -1
  168. package/dist/core/profiles.js.map +0 -1
  169. package/dist/core/set-values.d.ts.map +0 -1
  170. package/dist/core/set-values.js.map +0 -1
  171. package/dist/core/submission-journal.d.ts.map +0 -1
  172. package/dist/core/submission-journal.js.map +0 -1
  173. package/dist/core/types.d.ts.map +0 -1
  174. package/dist/core/types.js.map +0 -1
  175. package/dist/core/version.d.ts.map +0 -1
  176. package/dist/core/version.js.map +0 -1
  177. package/dist/core/wait.d.ts.map +0 -1
  178. package/dist/core/wait.js.map +0 -1
  179. package/dist/index.d.ts.map +0 -1
  180. package/dist/index.js.map +0 -1
  181. package/dist/mcp/render.d.ts.map +0 -1
  182. package/dist/mcp/render.js.map +0 -1
  183. package/dist/mcp/server.d.ts.map +0 -1
  184. package/dist/mcp/server.js.map +0 -1
@@ -0,0 +1,37 @@
1
+ import { type StudioApi, type Resource } from './controller.js';
2
+ import { createSaveQueue } from './save-queue.js';
3
+ import { type LocalAsset } from './asset-model.js';
4
+ interface Clock {
5
+ now(): number;
6
+ setTimeout(fn: () => void, ms: number): unknown;
7
+ clearTimeout(handle: unknown): void;
8
+ }
9
+ type Observation = Resource<LocalAsset> & {
10
+ notice?: string;
11
+ };
12
+ export declare function createAssetController(options: {
13
+ api: StudioApi;
14
+ queue?: ReturnType<typeof createSaveQueue>;
15
+ clock?: Clock;
16
+ onChange?: () => void;
17
+ }): {
18
+ state: Record<string, Observation>;
19
+ read: (id: string, opts?: {
20
+ manual?: boolean;
21
+ automatic?: boolean;
22
+ lazy?: boolean;
23
+ }) => Promise<void>;
24
+ markVisible: (id: string, on: boolean) => void;
25
+ setPageVisible: (value: boolean) => void;
26
+ beginList: () => {
27
+ serial: number;
28
+ inFlight: Set<string>;
29
+ };
30
+ rememberList: (assets: LocalAsset[], ticket: ReturnType<() => {
31
+ serial: number;
32
+ inFlight: Set<string>;
33
+ }>) => void;
34
+ dispose: () => void;
35
+ };
36
+ export {};
37
+ //# sourceMappingURL=asset-controller.d.ts.map
@@ -0,0 +1,191 @@
1
+ import { uiError } from './controller.js';
2
+ import { createSaveQueue } from './save-queue.js';
3
+ import { pendingDelay, backoffDelay } from './save-model.js';
4
+ import { parseAssetMetadata } from './asset-model.js';
5
+ export function createAssetController(options) {
6
+ const state = {}, queue = options.queue ?? createSaveQueue(), clock = options.clock ?? { now: Date.now, setTimeout: (fn, ms) => setTimeout(fn, ms), clearTimeout: (h) => clearTimeout(h) };
7
+ const follows = new Map(), visible = new Set(), lazy = new Set(), tickets = new Map();
8
+ let epoch = 0, serial = 0, pageVisible = true, timer;
9
+ const paused = Symbol('paused'), expired = Symbol('expired'), capped = Symbol('follow-limit'), emit = () => options.onChange?.();
10
+ const context = (id) => {
11
+ let f = follows.get(id);
12
+ if (!f) {
13
+ f = { count: 0, failures: 0 };
14
+ follows.set(id, f);
15
+ }
16
+ return f;
17
+ };
18
+ const key = (id) => `asset:${epoch}:${id}`;
19
+ function stopTimer() {
20
+ if (timer !== undefined)
21
+ clock.clearTimeout(timer);
22
+ timer = undefined;
23
+ }
24
+ function expire(id, f) {
25
+ if (f.start === undefined || clock.now() < f.start + 120000)
26
+ return false;
27
+ f.next = undefined;
28
+ if (state[id])
29
+ state[id].notice = f.failures ? '暂不可核对 · 核对文件状态' : '核验尚未完成 · 核对文件状态';
30
+ queue.cancel(key(id), expired);
31
+ return true;
32
+ }
33
+ function arm() {
34
+ stopTimer();
35
+ if (!pageVisible)
36
+ return;
37
+ const due = [];
38
+ for (const [id, f] of follows) {
39
+ if (expire(id, f))
40
+ continue;
41
+ if (f.busy) {
42
+ if (f.start !== undefined)
43
+ due.push(f.start + 120000);
44
+ }
45
+ else if (f.next !== undefined)
46
+ due.push(f.start === undefined ? f.next : Math.min(f.next, f.start + 120000));
47
+ }
48
+ if (due.length)
49
+ timer = clock.setTimeout(tick, Math.max(0, Math.min(...due) - clock.now()));
50
+ }
51
+ function tick() {
52
+ timer = undefined;
53
+ if (!pageVisible)
54
+ return;
55
+ for (const [id, f] of follows)
56
+ if (!expire(id, f) && !f.busy && f.next !== undefined && f.next <= clock.now())
57
+ void read(id, { automatic: true });
58
+ arm();
59
+ emit();
60
+ }
61
+ function beginList() {
62
+ return { serial: ++serial, inFlight: new Set([...follows].filter(([, f]) => f.busy).map(([id]) => id)) };
63
+ }
64
+ function rememberList(assets, ticket) {
65
+ for (const a of assets) {
66
+ if (ticket.inFlight.has(a.assetId) || (tickets.get(a.assetId) ?? 0) > ticket.serial)
67
+ continue;
68
+ tickets.set(a.assetId, ticket.serial);
69
+ state[a.assetId] = { status: 'ready', value: a };
70
+ if (a.integrity?.integrityCheck === 'IDLE') {
71
+ const f = context(a.assetId);
72
+ f.start = undefined;
73
+ f.next = undefined;
74
+ }
75
+ }
76
+ arm();
77
+ emit();
78
+ }
79
+ function read(id, opts = {}) {
80
+ const f = context(id);
81
+ if (f.busy)
82
+ return f.busy;
83
+ const before = state[id];
84
+ if (!before?.value)
85
+ return Promise.resolve();
86
+ const started = epoch, oldNext = f.next, ticket = ++serial;
87
+ f.next = undefined;
88
+ if (opts.manual) {
89
+ f.start = undefined;
90
+ f.count = 0;
91
+ f.failures = 0;
92
+ }
93
+ tickets.set(id, ticket);
94
+ const loading = { ...before, status: 'loading' };
95
+ state[id] = loading;
96
+ emit();
97
+ const pending = (async () => {
98
+ try {
99
+ const reply = await queue.run(key(id), opts.manual ? 1 : 2, () => {
100
+ if (started !== epoch || !pageVisible || opts.lazy && !visible.has(id))
101
+ return Promise.resolve(paused);
102
+ if (expire(id, f))
103
+ return Promise.resolve(expired);
104
+ if (opts.automatic && f.start !== undefined && f.count >= 13)
105
+ return Promise.resolve(capped);
106
+ if (opts.lazy)
107
+ lazy.add(id);
108
+ if (opts.automatic)
109
+ f.count++;
110
+ return options.api(`assets/${id}`);
111
+ });
112
+ if (started !== epoch)
113
+ return;
114
+ if (reply === paused || reply === expired || reply === capped) {
115
+ if (reply === paused)
116
+ f.next = oldNext;
117
+ if (reply === capped)
118
+ f.next = f.start + 120000;
119
+ if (state[id] === loading)
120
+ state[id] = { ...before, ...(state[id].notice ? { notice: state[id].notice } : {}) };
121
+ return;
122
+ }
123
+ const asset = parseAssetMetadata(reply, id);
124
+ if ((tickets.get(id) ?? 0) > ticket)
125
+ return;
126
+ state[id] = { status: 'ready', value: asset };
127
+ f.failures = 0;
128
+ if (asset.integrity.integrityCheck === 'PENDING') {
129
+ f.start ??= clock.now();
130
+ if (!expire(id, f))
131
+ f.next = f.count < 13 ? clock.now() + pendingDelay(f.count) : f.start + 120000;
132
+ }
133
+ else {
134
+ f.start = undefined;
135
+ f.next = undefined;
136
+ }
137
+ }
138
+ catch (error) {
139
+ if (started !== epoch)
140
+ return;
141
+ state[id] = { ...state[id], status: 'error', error: uiError(error), notice: '文件状态尚未确认 · 核对文件状态' };
142
+ const status = error?.status ?? uiError(error).httpStatus;
143
+ const transient = status === 503 || status === undefined && (!(error?.code) || uiError(error).code === 'STUDIO_REQUEST_FAILED');
144
+ if (transient && f.start !== undefined && !expire(id, f))
145
+ f.next = clock.now() + backoffDelay(f.failures++);
146
+ else
147
+ f.next = undefined;
148
+ }
149
+ finally {
150
+ if (started === epoch) {
151
+ f.busy = undefined;
152
+ arm();
153
+ emit();
154
+ }
155
+ }
156
+ })();
157
+ f.busy = pending;
158
+ return pending;
159
+ }
160
+ function markVisible(id, on) {
161
+ if (on)
162
+ visible.add(id);
163
+ else
164
+ visible.delete(id);
165
+ if (pageVisible && on && !lazy.has(id) && state[id]?.value)
166
+ void read(id, { lazy: true });
167
+ }
168
+ function setPageVisible(value) {
169
+ pageVisible = value;
170
+ if (value)
171
+ for (const id of visible)
172
+ if (!lazy.has(id) && state[id]?.value)
173
+ void read(id, { lazy: true });
174
+ arm();
175
+ emit();
176
+ }
177
+ function dispose() {
178
+ epoch++;
179
+ queue.reset('asset:');
180
+ stopTimer();
181
+ follows.clear();
182
+ visible.clear();
183
+ lazy.clear();
184
+ tickets.clear();
185
+ for (const id of Object.keys(state))
186
+ delete state[id];
187
+ emit();
188
+ }
189
+ return { state, read, markVisible, setPageVisible, beginList, rememberList, dispose };
190
+ }
191
+ //# sourceMappingURL=asset-controller.js.map
@@ -0,0 +1,29 @@
1
+ export interface AssetIntegrity {
2
+ file: 'NOT_CHECKED' | 'ABSENT' | 'PARTIAL' | 'VERIFIED' | 'MISSING' | 'MODIFIED' | 'UNSAFE' | 'UNKNOWN';
3
+ checkedAt: string | null;
4
+ integrityCheck: 'IDLE' | 'PENDING';
5
+ }
6
+ export interface LocalAsset {
7
+ assetId: string;
8
+ displayName: string;
9
+ mediaType: string;
10
+ byteLength: number;
11
+ integrity?: AssetIntegrity;
12
+ }
13
+ export interface ObservedAsset extends LocalAsset {
14
+ integrity: AssetIntegrity;
15
+ }
16
+ /** A fresh local list receipt, shared with Canvas C1. Loading/error values remain stale, not new receipts. */
17
+ export declare function parseLocalAssetReceipt(resource: unknown): {
18
+ assets: LocalAsset[];
19
+ recoveryIssues: unknown[];
20
+ } | undefined;
21
+ export declare function assetFileLink(asset: LocalAsset): {
22
+ canOpen: boolean;
23
+ reason: string;
24
+ };
25
+ export declare function parseAssetMetadata(value: unknown, assetId: string): ObservedAsset;
26
+ export declare function assetPresentation(asset: LocalAsset, observationFailed?: boolean): {
27
+ status: string;
28
+ };
29
+ //# sourceMappingURL=asset-model.d.ts.map
@@ -0,0 +1,51 @@
1
+ import { isId, isRecord, invalidSaveResponse } from './save-model.js';
2
+ /** A fresh local list receipt, shared with Canvas C1. Loading/error values remain stale, not new receipts. */
3
+ export function parseLocalAssetReceipt(resource) {
4
+ if (!isRecord(resource) || resource.status !== 'ready')
5
+ return undefined;
6
+ const value = resource.value;
7
+ if (!isRecord(value) || !Array.isArray(value.assets) || !Array.isArray(value.recoveryIssues))
8
+ return invalidSaveResponse();
9
+ for (const asset of value.assets) {
10
+ if (!isRecord(asset) || !isId(asset.assetId) || typeof asset.displayName !== 'string' || typeof asset.mediaType !== 'string' ||
11
+ !Number.isSafeInteger(asset.byteLength) || asset.byteLength < 1)
12
+ return invalidSaveResponse();
13
+ }
14
+ if (new Set(value.assets.map(asset => asset.assetId)).size !== value.assets.length)
15
+ return invalidSaveResponse();
16
+ return value;
17
+ }
18
+ export function assetFileLink(asset) {
19
+ switch (asset.integrity?.file) {
20
+ case 'MISSING':
21
+ return { canOpen: false, reason: '文件已缺失,无法打开本机文件。' };
22
+ case 'UNSAFE':
23
+ return { canOpen: false, reason: '文件安全状态异常,暂不能打开本机文件。' };
24
+ case 'MODIFIED':
25
+ return { canOpen: true, reason: '文件已被修改,当前内容可能与原素材不同。' };
26
+ default:
27
+ return { canOpen: true, reason: '' };
28
+ }
29
+ }
30
+ export function parseAssetMetadata(value, assetId) {
31
+ if (!isRecord(value) || !(value.scope === null || isRecord(value.scope) && (value.scope.rootId === null || isId(value.scope.rootId)) && isId(value.scope.connectionId)) || !isRecord(value.asset))
32
+ return invalidSaveResponse();
33
+ const a = value.asset, fact = a.integrity;
34
+ if (a.assetId !== assetId || !isId(a.assetId) || typeof a.displayName !== 'string' || typeof a.mediaType !== 'string' || typeof a.byteLength !== 'number' || !Number.isSafeInteger(a.byteLength) || a.byteLength < 1 || !isRecord(fact) ||
35
+ !['NOT_CHECKED', 'ABSENT', 'PARTIAL', 'VERIFIED', 'MISSING', 'MODIFIED', 'UNSAFE', 'UNKNOWN'].includes(fact.file) || !['IDLE', 'PENDING'].includes(fact.integrityCheck) || !(fact.checkedAt === null || typeof fact.checkedAt === 'string' && Number.isFinite(Date.parse(fact.checkedAt))) || fact.file === 'VERIFIED' && !fact.checkedAt || fact.integrityCheck === 'PENDING' && fact.file !== 'NOT_CHECKED')
36
+ return invalidSaveResponse();
37
+ return a;
38
+ }
39
+ export function assetPresentation(asset, observationFailed = false) {
40
+ if (observationFailed)
41
+ return { status: '文件状态尚未确认' };
42
+ const fact = asset.integrity;
43
+ if (!fact)
44
+ return { status: '文件状态尚未读取' };
45
+ if (fact.integrityCheck === 'PENDING')
46
+ return { status: '正在核对文件' };
47
+ if (fact.file === 'VERIFIED' && fact.checkedAt)
48
+ return { status: '本机文件 · 当前已核验' };
49
+ return { status: { NOT_CHECKED: '文件尚未核验', MISSING: '文件现已缺失', MODIFIED: '文件现已变更', UNSAFE: '文件安全状态异常', UNKNOWN: '文件状态未确认', ABSENT: '文件不存在', PARTIAL: '文件不完整', VERIFIED: '文件状态未确认' }[fact.file] };
50
+ }
51
+ //# sourceMappingURL=asset-model.js.map
@@ -0,0 +1,113 @@
1
+ import { type MediaModel, type Mode, type PublicRun, type PublicFailure } from './model.js';
2
+ import { type SaveState } from './save-controller.js';
3
+ import { createAssetController } from './asset-controller.js';
4
+ import { type LocalAsset } from './asset-model.js';
5
+ export interface Resource<T> {
6
+ status: 'idle' | 'loading' | 'ready' | 'error';
7
+ value?: T;
8
+ error?: UiError;
9
+ }
10
+ export type UiError = Omit<PublicFailure, 'type'> & {
11
+ type?: string;
12
+ };
13
+ interface Draft {
14
+ modelId: string;
15
+ fields: Record<string, string>;
16
+ savedAt?: string;
17
+ }
18
+ interface Drafts {
19
+ revision: number;
20
+ drafts: Partial<Record<Mode, Draft>>;
21
+ }
22
+ export interface Session {
23
+ storage: {
24
+ configured: boolean;
25
+ outputDir?: string;
26
+ };
27
+ cloud: {
28
+ connected: boolean;
29
+ gateway?: string;
30
+ };
31
+ }
32
+ export type Asset = LocalAsset;
33
+ export interface State {
34
+ local: Resource<Session>;
35
+ catalog: Resource<MediaModel[]>;
36
+ balance: Resource<{
37
+ availableCredits: number;
38
+ reservedCredits: number;
39
+ }>;
40
+ runs: Resource<PublicRun[]>;
41
+ assets: Resource<{
42
+ assets: Asset[];
43
+ recoveryIssues: unknown[];
44
+ }>;
45
+ drafts: Resource<Drafts>;
46
+ mode: Mode;
47
+ edits: Record<Mode, Draft>;
48
+ dirty: Record<Mode, boolean>;
49
+ connected: boolean;
50
+ gateway?: string;
51
+ connecting: boolean;
52
+ quoteBusy: boolean;
53
+ submitBusy: boolean;
54
+ saving: boolean;
55
+ refreshing: boolean;
56
+ quote?: PublicRun;
57
+ error?: UiError;
58
+ notice: string;
59
+ sessionExpired: boolean;
60
+ saves: SaveState;
61
+ assetChecks: ReturnType<typeof createAssetController>['state'];
62
+ }
63
+ export type StudioApi = (route: string, body?: unknown) => Promise<any>;
64
+ export declare function createLocalApi(fetcher?: typeof fetch, onUnauthorized?: () => void): StudioApi & {
65
+ request: typeof fetch;
66
+ };
67
+ export declare function uiError(error: unknown): UiError;
68
+ export declare function createStudioController(options: {
69
+ api: StudioApi;
70
+ onChange?: (state: State) => void;
71
+ uuid?: () => string;
72
+ now?: () => number;
73
+ }): {
74
+ state: State;
75
+ expireSession: () => void;
76
+ readOutputs: (runId: string, retry?: boolean) => Promise<void>;
77
+ saveOutput: (runId: string, outputId: string) => Promise<void>;
78
+ checkOutput: (runId: string, outputId: string) => Promise<void>;
79
+ readSave: (id: string, readOptions?: {
80
+ manual?: boolean;
81
+ automatic?: boolean;
82
+ lazy?: boolean;
83
+ }) => Promise<void>;
84
+ retrySave: (id: string) => Promise<void>;
85
+ markSaveVisible: (id: string, onScreen: boolean) => void;
86
+ readAsset: (id: string, opts?: {
87
+ manual?: boolean;
88
+ automatic?: boolean;
89
+ lazy?: boolean;
90
+ }) => Promise<void>;
91
+ markAssetVisible: (id: string, on: boolean) => void;
92
+ setSavePageVisible(value: boolean): void;
93
+ disposeSaves(): void;
94
+ bindSaves(): Promise<void>;
95
+ init(): Promise<void>;
96
+ setMode(mode: Mode): void;
97
+ selectModel(id: string): void;
98
+ setField(key: string, value: string): void;
99
+ saveDraft(): Promise<void>;
100
+ rereadDrafts(): Promise<void>;
101
+ connect(): Promise<void>;
102
+ disconnect(): Promise<void>;
103
+ refreshCloud: () => Promise<void>;
104
+ quote(): Promise<void>;
105
+ confirm(): Promise<void>;
106
+ refreshRun(id: string): Promise<void>;
107
+ refreshAssets: (options?: {
108
+ afterWrite?: boolean;
109
+ }) => Promise<void>;
110
+ reportError: (error: unknown) => void;
111
+ };
112
+ export {};
113
+ //# sourceMappingURL=controller.d.ts.map