@smart-tools/t3-code-pixso-mcp-assistant 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{PixsoAssistantService-BWdD4LmW.d.mts → PixsoAssistantService-CECSOLYb.d.mts} +69 -66
- package/dist/PixsoAssistantService-x1jLli4a.mjs +109 -0
- package/dist/contracts/index.d.mts +1656 -56
- package/dist/contracts/index.mjs +1 -1
- package/dist/galleryState-DvtxfQ-P.mjs +1 -0
- package/dist/panel-DDqwWCE7.mjs +1 -0
- package/dist/resolvedNodes-CqxO3XOM.d.mts +42 -0
- package/dist/scan-B_SM6uoL.d.mts +2791 -0
- package/dist/server/index.d.mts +4 -3
- package/dist/server/index.mjs +1 -1
- package/dist/server/testing.d.mts +3 -2
- package/dist/server/testing.mjs +1 -1
- package/dist/web/index.d.mts +16 -3
- package/dist/web/index.mjs +7 -10
- package/package.json +7 -9
- package/dist/PixsoAssistantService-DE6ZFSfz.mjs +0 -113
- package/dist/constants-C3TxS7N-.mjs +0 -1
- package/dist/errors-CzFjWbus.d.mts +0 -10
- package/dist/localization-C6n18NsP.d.mts +0 -3
- package/dist/panel-DWzV5ian.mjs +0 -1
- package/dist/renderPreview-BNqmGtPz.mjs +0 -1
- package/dist/scan-CjlRisOD.d.mts +0 -906
- package/dist/synthetic/index.d.mts +0 -31
- package/dist/synthetic/index.mjs +0 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { O as CardDetail, S as CardSummary, T as PanelSnapshot, d as RemoteToolsListResult, f as ReparseResult, g as ScanReportData, j as CatalogSnapshot, l as RemoteCheckResult, m as ScanOrigin, n as LatestScanReport, o as ProbeResult, p as ScanJobState, t as CheckResult, u as RemoteTarget, w as GroupsMutateOp } from "./scan-B_SM6uoL.mjs";
|
|
2
|
+
import { a as PixsoAssistantError, r as ResolvedNodesEnvelope } from "./resolvedNodes-CqxO3XOM.mjs";
|
|
3
3
|
import * as Context from "effect/Context";
|
|
4
4
|
import * as Effect from "effect/Effect";
|
|
5
5
|
import * as Layer from "effect/Layer";
|
|
6
|
-
import * as FileSystem from "effect/FileSystem";
|
|
7
6
|
import * as Path from "effect/Path";
|
|
7
|
+
import { PixsoCallResult, PixsoListResult, PixsoRawCallResult, PixsoRawListResult } from "@smart-tools/pixso-core/node";
|
|
8
|
+
import * as FileSystem from "effect/FileSystem";
|
|
8
9
|
import * as Stream from "effect/Stream";
|
|
9
|
-
|
|
10
10
|
interface PixsoAssistantConfigShape {
|
|
11
11
|
readonly rootDir: string;
|
|
12
12
|
}
|
|
@@ -15,18 +15,29 @@ declare class PixsoAssistantConfig extends PixsoAssistantConfig_base {}
|
|
|
15
15
|
interface PersistScanInput {
|
|
16
16
|
readonly dslRaw: string;
|
|
17
17
|
readonly catalogRaw: string | null;
|
|
18
|
+
readonly imagePngBase64?: string | null;
|
|
18
19
|
readonly capturedAtIso: string;
|
|
19
20
|
readonly card: Omit<CardDetail, "id" | "importedAtIso" | "catalogHash">;
|
|
20
21
|
readonly summary: Omit<CardSummary, "id" | "importedAtIso">;
|
|
21
22
|
readonly report: ScanReportData;
|
|
23
|
+
readonly origin?: ScanOrigin;
|
|
24
|
+
readonly provenance?: {
|
|
25
|
+
readonly source: "local" | "remote";
|
|
26
|
+
readonly fileKey: string | null;
|
|
27
|
+
readonly designUrl: string | null;
|
|
28
|
+
};
|
|
29
|
+
readonly resolvedNodes?: ResolvedNodesEnvelope;
|
|
22
30
|
}
|
|
23
31
|
interface PersistScanResult {
|
|
24
32
|
readonly id: string;
|
|
25
33
|
readonly duplicate: boolean;
|
|
34
|
+
readonly enriched: ReadonlyArray<"image" | "components">;
|
|
26
35
|
}
|
|
27
36
|
interface ReparseRebuildInput {
|
|
28
37
|
readonly dslRaw: string;
|
|
29
38
|
readonly catalogRaw: string | null;
|
|
39
|
+
readonly rootGuid: string;
|
|
40
|
+
readonly resolvedNodes: ResolvedNodesEnvelope | null;
|
|
30
41
|
}
|
|
31
42
|
type ReparseRebuild = (input: ReparseRebuildInput) => {
|
|
32
43
|
readonly card: PersistScanInput["card"];
|
|
@@ -36,11 +47,13 @@ interface ScanStoreShape {
|
|
|
36
47
|
readonly getSnapshot: () => Effect.Effect<PanelSnapshot, PixsoAssistantError>;
|
|
37
48
|
readonly getCard: (id: string) => Effect.Effect<CardDetail, PixsoAssistantError>;
|
|
38
49
|
readonly getCardRaw: (id: string) => Effect.Effect<string, PixsoAssistantError>;
|
|
50
|
+
readonly getCardImage: (id: string) => Effect.Effect<string, PixsoAssistantError>;
|
|
39
51
|
readonly getCatalogRaw: (catalogHash: string) => Effect.Effect<{
|
|
40
52
|
readonly raw: string;
|
|
41
53
|
readonly capturedAtIso: string;
|
|
42
54
|
}, PixsoAssistantError>;
|
|
43
55
|
readonly findScanByNodeId: (nodeId: string) => Effect.Effect<string | null, PixsoAssistantError>;
|
|
56
|
+
readonly getResolvedNodes: (id: string) => Effect.Effect<ResolvedNodesEnvelope | null, PixsoAssistantError>;
|
|
44
57
|
readonly removeCard: (id: string) => Effect.Effect<void, PixsoAssistantError>;
|
|
45
58
|
readonly mutateGallery: (mutation: GroupsMutateOp) => Effect.Effect<void, PixsoAssistantError>;
|
|
46
59
|
readonly getLatestReport: () => Effect.Effect<LatestScanReport | null, PixsoAssistantError>;
|
|
@@ -48,68 +61,26 @@ interface ScanStoreShape {
|
|
|
48
61
|
readonly recordReport: (report: LatestScanReport) => Effect.Effect<void, PixsoAssistantError>;
|
|
49
62
|
readonly recordCheck: (check: CheckResult) => Effect.Effect<void, PixsoAssistantError>;
|
|
50
63
|
readonly recordProbe: (probe: ProbeResult) => Effect.Effect<void, PixsoAssistantError>;
|
|
64
|
+
readonly getRemoteToken: () => Effect.Effect<string | null, PixsoAssistantError>;
|
|
65
|
+
readonly setRemoteToken: (token: string) => Effect.Effect<void, PixsoAssistantError>;
|
|
66
|
+
readonly clearRemoteToken: () => Effect.Effect<void, PixsoAssistantError>;
|
|
67
|
+
readonly getRemoteByDefault: () => Effect.Effect<boolean, PixsoAssistantError>;
|
|
68
|
+
readonly setRemoteByDefault: (value: boolean) => Effect.Effect<void, PixsoAssistantError>;
|
|
51
69
|
readonly reparseScans: (rebuild: ReparseRebuild) => Effect.Effect<ReparseResult, PixsoAssistantError>;
|
|
52
70
|
readonly diagnosticsDir: string;
|
|
53
71
|
}
|
|
54
72
|
declare const ScanStore_base: Context.ServiceClass<ScanStore, "@smart-tools/t3-code-pixso-mcp-assistant/server/store/ScanStore", ScanStoreShape>;
|
|
55
73
|
declare class ScanStore extends ScanStore_base {}
|
|
56
|
-
declare const ScanStoreLive: Layer.Layer<ScanStore, never,
|
|
74
|
+
declare const ScanStoreLive: Layer.Layer<ScanStore, never, PixsoAssistantConfig | Path.Path | FileSystem.FileSystem>;
|
|
57
75
|
declare const RAW_DSL_KEEP = 40;
|
|
76
|
+
declare const RAW_DSL_BUDGET: number;
|
|
58
77
|
declare const RAW_CATALOG_KEEP = 20;
|
|
78
|
+
declare const RAW_CATALOG_BUDGET: number;
|
|
59
79
|
declare const sameGeneration: (left: CardSummary, right: CardSummary) => boolean;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
readonly
|
|
63
|
-
|
|
64
|
-
readonly unobserved?: boolean;
|
|
65
|
-
}
|
|
66
|
-
declare const DSL_CONTRACT_MANIFEST: ReadonlyMap<string, ContractManifestEntry>;
|
|
67
|
-
declare function normalizeContractPath(line: string): string | null;
|
|
68
|
-
declare function normalizeCatalogContractPath(line: string): string | null;
|
|
69
|
-
declare const CATALOG_CONTRACT_MANIFEST: ReadonlyMap<string, ContractManifestEntry>;
|
|
70
|
-
interface PixsoWireTool {
|
|
71
|
-
readonly name: string;
|
|
72
|
-
readonly description: string;
|
|
73
|
-
readonly params: ReadonlyArray<{
|
|
74
|
-
readonly name: string;
|
|
75
|
-
readonly type: string;
|
|
76
|
-
readonly required: boolean;
|
|
77
|
-
readonly description?: string;
|
|
78
|
-
readonly enumValues?: ReadonlyArray<string>;
|
|
79
|
-
}>;
|
|
80
|
-
}
|
|
81
|
-
interface PixsoRawTool extends PixsoWireTool {
|
|
82
|
-
readonly inputSchema: unknown;
|
|
83
|
-
}
|
|
84
|
-
type PixsoListResult = {
|
|
85
|
-
readonly ok: true;
|
|
86
|
-
readonly tools: ReadonlyArray<PixsoWireTool>;
|
|
87
|
-
readonly ms: number;
|
|
88
|
-
} | PixsoFailure;
|
|
89
|
-
type PixsoRawListResult = {
|
|
90
|
-
readonly ok: true;
|
|
91
|
-
readonly tools: ReadonlyArray<PixsoRawTool>;
|
|
92
|
-
readonly ms: number;
|
|
93
|
-
} | PixsoFailure;
|
|
94
|
-
type PixsoCallResult = {
|
|
95
|
-
readonly ok: true;
|
|
96
|
-
readonly texts: ReadonlyArray<string>;
|
|
97
|
-
readonly ms: number;
|
|
98
|
-
} | PixsoFailure;
|
|
99
|
-
type PixsoRawCallResult = {
|
|
100
|
-
readonly ok: true;
|
|
101
|
-
readonly result: unknown;
|
|
102
|
-
readonly texts: ReadonlyArray<string>;
|
|
103
|
-
readonly isError: boolean;
|
|
104
|
-
readonly ms: number;
|
|
105
|
-
} | PixsoFailure;
|
|
106
|
-
interface PixsoFailure {
|
|
107
|
-
readonly ok: false;
|
|
108
|
-
readonly timedOut: boolean;
|
|
109
|
-
readonly origin: "transport" | "tool";
|
|
110
|
-
readonly message: string;
|
|
111
|
-
readonly ms: number;
|
|
112
|
-
}
|
|
80
|
+
declare const budgetEvictions: (window: ReadonlyArray<{
|
|
81
|
+
readonly hash: string;
|
|
82
|
+
readonly bytes: number | null;
|
|
83
|
+
}>, budget: number) => ReadonlyArray<string>;
|
|
113
84
|
interface PixsoMcpShape {
|
|
114
85
|
readonly endpoint: string;
|
|
115
86
|
readonly callTimeoutMs: number;
|
|
@@ -120,19 +91,36 @@ interface PixsoMcpShape {
|
|
|
120
91
|
}
|
|
121
92
|
declare const PixsoMcp_base: Context.ServiceClass<PixsoMcp, "@smart-tools/t3-code-pixso-mcp-assistant/server/mcp/PixsoMcp", PixsoMcpShape>;
|
|
122
93
|
declare class PixsoMcp extends PixsoMcp_base {}
|
|
123
|
-
declare const makePixsoMcp: (endpoint: string, timeoutMs?: number) => PixsoMcpShape;
|
|
94
|
+
declare const makePixsoMcp: (endpoint: string, timeoutMs?: number, headers?: Readonly<Record<string, string>>) => PixsoMcpShape;
|
|
124
95
|
declare const PixsoMcpLive: Layer.Layer<PixsoMcp, never, never>;
|
|
96
|
+
interface PixsoRemoteMcpShape {
|
|
97
|
+
readonly makeClient: (headers: Readonly<Record<string, string>>) => PixsoMcpShape;
|
|
98
|
+
}
|
|
99
|
+
declare const PixsoRemoteMcp_base: Context.ServiceClass<PixsoRemoteMcp, "@smart-tools/t3-code-pixso-mcp-assistant/server/mcp/PixsoMcp/PixsoRemoteMcp", PixsoRemoteMcpShape>;
|
|
100
|
+
declare class PixsoRemoteMcp extends PixsoRemoteMcp_base {}
|
|
101
|
+
interface NodesFetchPolicyShape {
|
|
102
|
+
readonly enabled: boolean;
|
|
103
|
+
}
|
|
104
|
+
declare const NodesFetchPolicy_base: Context.ServiceClass<NodesFetchPolicy, "@smart-tools/t3-code-pixso-mcp-assistant/server/scan/resolveNodes/NodesFetchPolicy", NodesFetchPolicyShape>;
|
|
105
|
+
declare class NodesFetchPolicy extends NodesFetchPolicy_base {}
|
|
106
|
+
declare const NodesFetchPolicyLive: Layer.Layer<NodesFetchPolicy, never, never>;
|
|
107
|
+
interface RemoteScanRequest {
|
|
108
|
+
readonly target: RemoteTarget;
|
|
109
|
+
readonly mcp: PixsoMcpShape;
|
|
110
|
+
}
|
|
125
111
|
interface ScanJobShape {
|
|
126
112
|
readonly state: Effect.Effect<ScanJobState>;
|
|
127
113
|
readonly changes: Stream.Stream<ScanJobState>;
|
|
128
|
-
readonly start: () => Effect.Effect<ScanJobState, PixsoAssistantError>;
|
|
114
|
+
readonly start: (remote?: RemoteScanRequest) => Effect.Effect<ScanJobState, PixsoAssistantError>;
|
|
115
|
+
readonly cancel: (origin: ScanOrigin) => Effect.Effect<ScanJobState>;
|
|
129
116
|
readonly check: () => Effect.Effect<CheckResult, PixsoAssistantError>;
|
|
130
117
|
readonly rescanDebug: () => Effect.Effect<LatestScanReport, PixsoAssistantError>;
|
|
118
|
+
readonly remoteScanProbe: (target: RemoteTarget, mcp: PixsoMcpShape) => Effect.Effect<LatestScanReport, PixsoAssistantError>;
|
|
131
119
|
readonly reparseStored: () => Effect.Effect<ReparseResult, PixsoAssistantError>;
|
|
132
120
|
}
|
|
133
121
|
declare const ScanJob_base: Context.ServiceClass<ScanJob, "@smart-tools/t3-code-pixso-mcp-assistant/server/scan/ScanJobService/ScanJob", ScanJobShape>;
|
|
134
122
|
declare class ScanJob extends ScanJob_base {}
|
|
135
|
-
declare const ScanJobLive: Layer.Layer<ScanJob, never, ScanStore | PixsoMcp>;
|
|
123
|
+
declare const ScanJobLive: Layer.Layer<ScanJob, never, ScanStore | PixsoMcp | NodesFetchPolicy>;
|
|
136
124
|
interface SettleLatchState {
|
|
137
125
|
readonly currentSeq: number;
|
|
138
126
|
readonly settledSeq: number | null;
|
|
@@ -141,11 +129,11 @@ declare const initialSettleLatch: SettleLatchState;
|
|
|
141
129
|
declare const settleWins: (state: SettleLatchState, seq: number) => boolean;
|
|
142
130
|
interface ProbeShape {
|
|
143
131
|
readonly run: () => Effect.Effect<ProbeResult, PixsoAssistantError>;
|
|
132
|
+
readonly runRemote: (target: RemoteTarget, mcp: PixsoMcpShape) => Effect.Effect<ProbeResult, PixsoAssistantError>;
|
|
144
133
|
}
|
|
145
134
|
declare const Probe_base: Context.ServiceClass<Probe, "@smart-tools/t3-code-pixso-mcp-assistant/server/probe/ProbeService/Probe", ProbeShape>;
|
|
146
135
|
declare class Probe extends Probe_base {}
|
|
147
|
-
declare const ProbeLive: Layer.Layer<Probe, never,
|
|
148
|
-
declare function summaryFromCard(card: CardDetail): CardSummary;
|
|
136
|
+
declare const ProbeLive: Layer.Layer<Probe, never, PixsoAssistantConfig | ScanStore | Path.Path | PixsoMcp | NodesFetchPolicy | FileSystem.FileSystem>;
|
|
149
137
|
declare const isStagedName: (entryName: string) => boolean;
|
|
150
138
|
interface PixsoAssistantShape {
|
|
151
139
|
readonly getSnapshot: () => Effect.Effect<PanelSnapshot, PixsoAssistantError>;
|
|
@@ -153,18 +141,33 @@ interface PixsoAssistantShape {
|
|
|
153
141
|
readonly getCardRaw: (id: string) => Effect.Effect<{
|
|
154
142
|
readonly raw: string;
|
|
155
143
|
}, PixsoAssistantError>;
|
|
144
|
+
readonly getCardImage: (id: string) => Effect.Effect<{
|
|
145
|
+
readonly pngBase64: string;
|
|
146
|
+
}, PixsoAssistantError>;
|
|
156
147
|
readonly removeCard: (id: string) => Effect.Effect<void, PixsoAssistantError>;
|
|
157
148
|
readonly mutateGallery: (mutation: GroupsMutateOp) => Effect.Effect<void, PixsoAssistantError>;
|
|
158
149
|
readonly getLatestReport: () => Effect.Effect<LatestScanReport | null, PixsoAssistantError>;
|
|
159
150
|
readonly getCatalog: (catalogHash: string) => Effect.Effect<CatalogSnapshot, PixsoAssistantError>;
|
|
160
|
-
readonly scanStart: () => Effect.Effect<ScanJobState, PixsoAssistantError>;
|
|
151
|
+
readonly scanStart: (target?: RemoteTarget) => Effect.Effect<ScanJobState, PixsoAssistantError>;
|
|
152
|
+
readonly scanCancel: (origin?: ScanOrigin) => Effect.Effect<ScanJobState, PixsoAssistantError>;
|
|
161
153
|
readonly scanStates: () => Stream.Stream<ScanJobState>;
|
|
162
154
|
readonly check: () => Effect.Effect<CheckResult, PixsoAssistantError>;
|
|
163
155
|
readonly probe: () => Effect.Effect<ProbeResult, PixsoAssistantError>;
|
|
164
156
|
readonly rescanDebug: () => Effect.Effect<LatestScanReport, PixsoAssistantError>;
|
|
165
157
|
readonly reparseStored: () => Effect.Effect<ReparseResult, PixsoAssistantError>;
|
|
158
|
+
readonly remoteTokenCheck: (token?: string) => Effect.Effect<RemoteCheckResult, PixsoAssistantError>;
|
|
159
|
+
readonly remoteTokenSave: (token: string) => Effect.Effect<{
|
|
160
|
+
readonly tokenSet: boolean;
|
|
161
|
+
}, PixsoAssistantError>;
|
|
162
|
+
readonly remoteTokenDelete: () => Effect.Effect<void, PixsoAssistantError>;
|
|
163
|
+
readonly remoteModeSet: (remoteByDefault: boolean) => Effect.Effect<void, PixsoAssistantError>;
|
|
164
|
+
readonly remoteToolsList: () => Effect.Effect<RemoteToolsListResult, PixsoAssistantError>;
|
|
165
|
+
readonly remoteScanProbe: (target: RemoteTarget) => Effect.Effect<LatestScanReport, PixsoAssistantError>;
|
|
166
|
+
readonly remoteFullProbe: (target: RemoteTarget) => Effect.Effect<ProbeResult, PixsoAssistantError>;
|
|
166
167
|
}
|
|
167
168
|
declare const PixsoAssistant_base: Context.ServiceClass<PixsoAssistant, "@smart-tools/t3-code-pixso-mcp-assistant/server/PixsoAssistantService/PixsoAssistant", PixsoAssistantShape>;
|
|
168
169
|
declare class PixsoAssistant extends PixsoAssistant_base {}
|
|
169
|
-
declare const PixsoAssistantLive: Layer.Layer<PixsoAssistant, never,
|
|
170
|
-
|
|
170
|
+
declare const PixsoAssistantLive: Layer.Layer<PixsoAssistant, never, PixsoAssistantConfig | Path.Path | PixsoMcp | FileSystem.FileSystem>;
|
|
171
|
+
declare const PixsoAssistantLiveWithRemoteMcp: Layer.Layer<PixsoAssistant, never, PixsoAssistantConfig | PixsoRemoteMcp | Path.Path | PixsoMcp | FileSystem.FileSystem>;
|
|
172
|
+
declare const PixsoAssistantLiveWithNodesFetchPolicy: (enabled: boolean) => Layer.Layer<PixsoAssistant, never, PixsoAssistantConfig | Path.Path | PixsoMcp | FileSystem.FileSystem>;
|
|
173
|
+
export { sameGeneration as A, PixsoRemoteMcpShape as C, RAW_DSL_BUDGET as D, RAW_CATALOG_KEEP as E, ScanStoreLive as F, ScanStoreShape as I, PixsoAssistantConfig as L, PersistScanResult as M, ReparseRebuild as N, RAW_DSL_KEEP as O, ScanStore as P, PixsoAssistantConfigShape as R, PixsoRemoteMcp as S, RAW_CATALOG_BUDGET as T, NodesFetchPolicyLive as _, PixsoAssistantShape as a, PixsoMcpLive as b, ProbeLive as c, initialSettleLatch as d, settleWins as f, NodesFetchPolicy as g, ScanJobShape as h, PixsoAssistantLiveWithRemoteMcp as i, PersistScanInput as j, budgetEvictions as k, ProbeShape as l, ScanJobLive as m, PixsoAssistantLive as n, isStagedName as o, ScanJob as p, PixsoAssistantLiveWithNodesFetchPolicy as r, Probe as s, PixsoAssistant as t, SettleLatchState as u, NodesFetchPolicyShape as v, makePixsoMcp as w, PixsoMcpShape as x, PixsoMcp as y };
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import{O as e,_t as t,c as n,k as r,l as i,n as a,p as o}from"./panel-DDqwWCE7.mjs";import{t as s}from"./galleryState-DvtxfQ-P.mjs";import*as c from"effect/Schema";import{L as l,LT as u,NODES_FETCH_ENABLED as d,PIXSO_MCP_ENDPOINT as f,PIXSO_REMOTE_MCP_ENDPOINT as p,PIXSO_REMOTE_TOOLS as m,PIXSO_REMOTE_TOOL_NAMES as h,PIXSO_TOOLS as g,USE_ASYNC_FOR_NODES_RESOLVE as _,catalogSnapshotOf as v,deriveProbeTarget as y,frameNameOf as b,isBaselineReadTool as x,isWriteToolName as S,nameSourceStrength as C,parseCatalogDump as w,sanitizePayload as T,synthesizeArgs as E,synthesizeRemoteArgs as ee}from"@smart-tools/pixso-core";import*as D from"effect/Context";import*as O from"effect/Effect";import*as k from"effect/Layer";import*as A from"effect/Path";import*as j from"effect/Ref";import{MAX_RESOLVED_NODES as te,assembleScan as M,buildByteDiff as N,buildReportData as P,classifyDslFailure as F,configurePixsoAssistantFonts as I,depthGate as ne,emptyReportInputs as L,emptyResolvedNodesEnvelope as re,isCatalogUsable as R,makePixsoClient as ie,nodeFetchArgs as ae,parsedFailureDetail as oe,postCatalogGates as se,preCatalogGates as ce,resolveNodes as le,resolvedNodesSummaryOf as ue,scanRootOfRaw as de,summaryFromCard as fe,unsupportedVersionDetail as pe,warningsDetail as me,writeSlimDump as z}from"@smart-tools/pixso-core/node";import*as B from"node:buffer";import*as V from"effect/Clock";import*as he from"effect/Deferred";import*as H from"effect/FileSystem";import*as U from"effect/Semaphore";import*as W from"effect/Option";import*as ge from"effect/unstable/sql/SqlClient";import*as _e from"effect/PlatformError";import*as ve from"node:process";import*as G from"node:crypto";import*as ye from"node:os";import*as be from"effect/Duration";import*as xe from"effect/Fiber";import*as Se from"effect/Stream";import*as K from"effect/SubscriptionRef";var Ce=class extends D.Service()(`@smart-tools/t3-code-pixso-mcp-assistant/server/mcp/PixsoMcp`){};const we=(e,t,n)=>{let r=ie(e,t,n);return{endpoint:r.endpoint,callTimeoutMs:r.callTimeoutMs,listTools:()=>O.promise(()=>r.listTools()),listToolsRaw:()=>O.promise(()=>r.listToolsRaw()),callTool:(e,t,n)=>O.promise(i=>r.callTool(e,t,n,i)),callToolRaw:(e,t,n)=>O.promise(i=>r.callToolRaw(e,t,n,i))}},Te=k.succeed(Ce,we(f));var Ee=class extends D.Service()(`@smart-tools/t3-code-pixso-mcp-assistant/server/mcp/PixsoMcp/PixsoRemoteMcp`){};const De=k.succeed(Ee,{makeClient:e=>we(p,void 0,e)});var Oe=class extends D.Service()(`@smart-tools/t3-code-pixso-mcp-assistant/server/ports/PixsoAssistantConfig`){},ke=class extends D.Service()(`@smart-tools/t3-code-pixso-mcp-assistant/server/ports/PixsoIndexSql`){},Ae=class extends D.Service()(`@smart-tools/t3-code-pixso-mcp-assistant/server/scan/resolveNodes/NodesFetchPolicy`){};const je=k.succeed(Ae,{enabled:d});function Me(e){return O.gen(function*(){let t=[],n=yield*O.context(),r=yield*O.promise(r=>le({root:e.root,concurrency:e.concurrency,alreadyResolved:e.alreadyResolved,fetchNode:(t,i)=>O.runPromiseWith(n)(e.fetchNode(t),{signal:i??r}),onProgress:(t,i)=>O.runPromiseWith(n)(e.onProgress(t,i),{signal:r}),log:(e,n)=>t.push({message:e,data:n}),...e.nodesFetchEnabled===void 0?{}:{nodesFetchEnabled:e.nodesFetchEnabled},signal:r}));for(let e of t)yield*e.data===void 0?O.logDebug(e.message):O.logDebug(e.message,e.data);return r})}const Ne=e=>e.includes(`.staged-`),Pe=(e,t)=>e.startsWith(`${t}.`)&&e.length>t.length+1,Fe=e=>ve.platform===`win32`?O.logDebug(`[pixso] store: directory sync unavailable on Windows`,{dirPath:e}):O.scoped(O.gen(function*(){yield*(yield*(yield*H.FileSystem).open(e,{flag:`r`})).sync})),Ie=e=>O.forEach([...new Set(e)],Fe,{discard:!0}),Le=e=>O.gen(function*(){let t=yield*H.FileSystem,n=yield*A.Path,r=[],i=e;for(;!(yield*t.exists(i));){r.push(i);let e=n.dirname(i);if(e===i)break;i=e}r.length!==0&&(yield*t.makeDirectory(e,{recursive:!0}),yield*Ie(r.map(e=>n.dirname(e))))}),Re=e=>O.scoped(O.gen(function*(){let t=yield*H.FileSystem,n=yield*A.Path,r=n.dirname(e.filePath);yield*Le(r);let i=yield*t.makeTempDirectoryScoped({directory:r,prefix:`${n.basename(e.filePath)}.`}),a=n.join(i,`contents.tmp`);yield*O.scoped(O.gen(function*(){let n=yield*t.open(a,{flag:`w`});yield*n.writeAll(e.contents),yield*n.sync})),yield*t.rename(a,e.filePath),yield*Fe(r)})),ze=e=>Re({filePath:e.filePath,contents:new TextEncoder().encode(e.contents)}),Be=/^[0-9a-f]{64}$/,q=e=>Be.test(e)?O.void:O.fail(_e.badArgument({module:`FileSystem`,method:`validateHash`,description:`invalid content hash: ${e}`})),J=e=>e.pipe(O.catch(e=>e.reason._tag===`NotFound`?O.succeed(null):O.fail(e))),Ve=(e,t)=>{let n=e.join(t,`scans`),r=e.join(t,`catalogs`);return{rootDir:t,scansDir:n,catalogsDir:r,quarantineDir:e.join(t,`_quarantine`),diagnosticsDir:e.join(t,`_diagnostics`),scanDir:t=>e.join(n,t),scanDsl:t=>e.join(n,t,`dsl.raw`),scanCard:t=>e.join(n,t,`card.json`),scanSummary:t=>e.join(n,t,`summary.json`),scanImage:t=>e.join(n,t,`preview.png`),scanNodes:t=>e.join(n,t,`nodes.json`),catalogBlob:t=>e.join(r,`${t}.json`)}},He=e=>{let t=(e,t)=>q(e).pipe(O.andThen(O.gen(function*(){return yield*(yield*H.FileSystem).readFileString(t)}))),n=n=>t(n,e.scanCard(n)),r=e=>J(n(e)),i=n=>t(n,e.scanDsl(n)),a=e=>J(i(e)),o=n=>t(n,e.scanSummary(n)),s=e=>J(o(e)),c=t=>q(t).pipe(O.andThen(O.gen(function*(){return yield*(yield*H.FileSystem).readFileString(e.catalogBlob(t))})));return{readCard:n,readCardOrNull:r,readDsl:i,readDslOrNull:a,readSummary:o,readSummaryOrNull:s,readCatalog:c,readCatalogOrNull:e=>J(c(e)),dslExists:t=>q(t).pipe(O.andThen(O.gen(function*(){return yield*(yield*H.FileSystem).exists(e.scanDsl(t))}))),imageExists:t=>q(t).pipe(O.andThen(O.gen(function*(){return yield*(yield*H.FileSystem).exists(e.scanImage(t))}))),readImageOrNull:t=>q(t).pipe(O.andThen(O.gen(function*(){return yield*J((yield*H.FileSystem).readFile(e.scanImage(t)))}))),writeImage:(t,n)=>q(t).pipe(O.andThen(Re({filePath:e.scanImage(t),contents:n}))),dslBytes:t=>q(t).pipe(O.andThen(O.gen(function*(){let n=yield*J((yield*H.FileSystem).stat(e.scanDsl(t)));return n===null?null:Number(n.size)}))),catalogBytes:t=>q(t).pipe(O.andThen(O.gen(function*(){let n=yield*J((yield*H.FileSystem).stat(e.catalogBlob(t)));return n===null?null:Number(n.size)}))),scanDirExists:t=>q(t).pipe(O.andThen(O.gen(function*(){return yield*(yield*H.FileSystem).exists(e.scanDir(t))}))),writeDsl:(t,n)=>q(t).pipe(O.andThen(ze({filePath:e.scanDsl(t),contents:n}))),readNodesOrNull:n=>J(t(n,e.scanNodes(n))),writeNodes:(t,n)=>q(t).pipe(O.andThen(ze({filePath:e.scanNodes(t),contents:n}))),writeCard:(t,n)=>q(t).pipe(O.andThen(ze({filePath:e.scanCard(t),contents:n}))),writeSummary:(t,n)=>q(t).pipe(O.andThen(ze({filePath:e.scanSummary(t),contents:n}))),writeCatalog:(t,n)=>q(t).pipe(O.andThen(O.gen(function*(){(yield*(yield*H.FileSystem).exists(e.catalogBlob(t)))||(yield*ze({filePath:e.catalogBlob(t),contents:n}))}))),removeDsl:t=>q(t).pipe(O.andThen(O.gen(function*(){yield*(yield*H.FileSystem).remove(e.scanDsl(t),{force:!0})}))),removeCatalog:t=>q(t).pipe(O.andThen(O.gen(function*(){yield*(yield*H.FileSystem).remove(e.catalogBlob(t),{force:!0})}))),removeScanDir:t=>q(t).pipe(O.andThen(O.gen(function*(){yield*(yield*H.FileSystem).remove(e.scanDir(t),{recursive:!0,force:!0})}))),listScanDirs:()=>O.gen(function*(){return yield*(yield*H.FileSystem).readDirectory(e.scansDir).pipe(O.orElseSucceed(()=>[]))}),listScanDirEntries:t=>q(t).pipe(O.andThen(O.gen(function*(){return yield*(yield*H.FileSystem).readDirectory(e.scanDir(t)).pipe(O.orElseSucceed(()=>[]))}))),listCatalogEntries:()=>O.gen(function*(){return yield*(yield*H.FileSystem).readDirectory(e.catalogsDir).pipe(O.orElseSucceed(()=>[]))}),listQuarantineEntries:()=>O.gen(function*(){return yield*(yield*H.FileSystem).readDirectory(e.quarantineDir).pipe(O.orElseSucceed(()=>[]))}),removeQuarantineEntry:t=>O.gen(function*(){let n=yield*H.FileSystem,r=yield*A.Path;yield*n.remove(r.join(e.quarantineDir,t),{recursive:!0,force:!0})}),statScanDir:t=>q(t).pipe(O.andThen(O.gen(function*(){return yield*J((yield*H.FileSystem).stat(e.scanDir(t)))}))),ensureScanDir:t=>q(t).pipe(O.andThen(Le(e.scanDir(t)))),paths:e}},Ue=C(`norm-name`)+.5,We=e=>e.nameSource===void 0?Ue:C(e.nameSource),Ge=e=>e.key===``?`name:${e.name}`:`key:${e.key}`;function Ke(e,t){let n=new Map(t.map(e=>[Ge(e),e]));return[...e.map(e=>{let t=n.get(Ge(e));return t===void 0?e:(n.delete(Ge(e)),We(t)<We(e)?t:e)}),...n.values()]}function qe(e,t){let n=e??[];return n.some(e=>e.source===t.source&&e.fileKey===t.fileKey&&e.designUrl===t.designUrl)?n:[...n,t]}function Je(e){return e.provenances!==void 0&&e.provenances.length>0?e.provenances:[{source:e.source??`local`,fileKey:null,guid:e.nodeId,designUrl:null,importedAtIso:e.importedAtIso}]}function Ye(e){return new Set((e.provenances??[]).flatMap(e=>e.fileKey===null?[]:[e.fileKey]))}function Xe(e,t){if(t===null)return!0;let n=Ye(e);return n.size===0||n.has(t)}function Ze(e){let{existing:t,incoming:n,incomingProvenance:r}=e,i=(t.source??`local`)===`local`,a=n.source===`local`&&!i;return{...t,root:a?n.root:t.root,pagePath:a?n.pagePath:t.pagePath,component:t.component??n.component,componentsUsed:Ke(t.componentsUsed,n.componentsUsed),dslVersion:t.dslVersion??n.dslVersion,...t.versionUnverified===!0||n.versionUnverified===!0?{versionUnverified:!0}:{},provenances:qe(Je(t),r)}}const Qe=e=>G.createHash(`sha256`).update(e,`utf8`).digest(`hex`),$e=`unsortedPinned`,et=`unsortedCollapsed`,Y=`lastReport`,tt=`lastProbe`,nt=`lastCheck`,rt=`remoteMode`,it=`remoteToken`,X=e=>typeof e==`string`?e:String(e),Z=e=>typeof e==`number`?e:Number(e),at=e=>Z(e)===1,ot=e=>e==null?null:X(e),st=e=>{let t=()=>e`SELECT * FROM scans WHERE deleted = 0 ORDER BY ordinal ASC`.pipe(O.map(e=>e.map(ct)),O.orDie),n=t=>e`SELECT * FROM scans WHERE dsl_hash = ${t} AND deleted = 0`.pipe(O.map(e=>e[0]===void 0?null:ct(e[0])),O.orDie),r=t=>e`SELECT * FROM scans WHERE dsl_hash = ${t}`.pipe(O.map(e=>e[0]===void 0?null:ct(e[0])),O.orDie),i=()=>e`SELECT COUNT(*) AS n FROM scans WHERE deleted = 0`.pipe(O.map(e=>Z(e[0]?.n??0)),O.orDie),a=t=>e`
|
|
2
|
+
SELECT dsl_hash FROM scans
|
|
3
|
+
WHERE node_id = ${t} AND deleted = 0
|
|
4
|
+
ORDER BY imported_at DESC LIMIT 1
|
|
5
|
+
`.pipe(O.map(e=>e[0]===void 0?null:X(e[0].dsl_hash)),O.orDie),o=t=>O.gen(function*(){yield*e`UPDATE scans SET deleted = 1 WHERE dsl_hash = ${t}`,yield*e`DELETE FROM group_by_card WHERE card_id = ${t}`,yield*e`DELETE FROM recents WHERE card_id = ${t}`}),s=()=>e`SELECT dsl_hash FROM scans WHERE deleted = 1`.pipe(O.map(e=>e.map(e=>X(e.dsl_hash))),O.orDie),c=t=>e`DELETE FROM scans WHERE dsl_hash = ${t}`,l=()=>O.gen(function*(){let t=yield*e`SELECT * FROM groups ORDER BY ordinal ASC`,n=yield*e`SELECT card_id, group_id FROM group_by_card`,r=yield*e`SELECT card_id FROM recents ORDER BY ordinal ASC`,i=yield*e`SELECT k, v FROM panel`,a=new Map(i.map(e=>[X(e.k),X(e.v)]));return{groups:t.map(e=>({id:X(e.id),name:X(e.name),pinned:at(e.pinned),collapsed:at(e.collapsed)})),groupByCardId:Object.fromEntries(n.map(e=>[X(e.card_id),X(e.group_id)])),unsortedPinned:a.get($e)!==`0`,unsortedCollapsed:a.get(et)===`1`,recents:r.map(e=>X(e.card_id))}}).pipe(O.orDie),u=t=>e`SELECT v FROM panel WHERE k = ${t}`.pipe(O.map(e=>e[0]===void 0?null:X(e[0].v)),O.orDie),d=e.literal(`catalog_hash IS NOT NULL AND deleted = 0`),f=t=>e`SELECT 1 FROM scans WHERE ${d} AND catalog_hash = ${t} LIMIT 1`.pipe(O.map(e=>e.length>0),O.orDie),p=(t,n)=>e`
|
|
6
|
+
SELECT dsl_hash FROM scans
|
|
7
|
+
WHERE deleted = 0 AND dsl_hash IS NOT ${n}
|
|
8
|
+
ORDER BY imported_at DESC, dsl_hash DESC
|
|
9
|
+
LIMIT -1 OFFSET ${t}
|
|
10
|
+
`.pipe(O.map(e=>e.map(e=>X(e.dsl_hash))),O.orDie),m=(t,n)=>e`
|
|
11
|
+
SELECT dsl_hash FROM scans
|
|
12
|
+
WHERE deleted = 0 AND dsl_hash IS NOT ${n}
|
|
13
|
+
ORDER BY imported_at DESC, dsl_hash DESC
|
|
14
|
+
LIMIT ${t}
|
|
15
|
+
`.pipe(O.map(e=>e.map(e=>X(e.dsl_hash))),O.orDie),h=(t,n)=>e`
|
|
16
|
+
SELECT catalog_hash, MAX(imported_at) AS newest FROM scans
|
|
17
|
+
WHERE ${d} AND catalog_hash IS NOT ${n}
|
|
18
|
+
GROUP BY catalog_hash
|
|
19
|
+
ORDER BY newest DESC, catalog_hash DESC
|
|
20
|
+
LIMIT -1 OFFSET ${t}
|
|
21
|
+
`.pipe(O.map(e=>e.map(e=>X(e.catalog_hash))),O.orDie),g=(t,n)=>e`
|
|
22
|
+
SELECT catalog_hash, MAX(imported_at) AS newest FROM scans
|
|
23
|
+
WHERE ${d} AND catalog_hash IS NOT ${n}
|
|
24
|
+
GROUP BY catalog_hash
|
|
25
|
+
ORDER BY newest DESC, catalog_hash DESC
|
|
26
|
+
LIMIT ${t}
|
|
27
|
+
`.pipe(O.map(e=>e.map(e=>X(e.catalog_hash))),O.orDie),_=t=>{let n=t.summary;return e`
|
|
28
|
+
INSERT INTO scans (
|
|
29
|
+
dsl_hash, ordinal, node_id, name, imported_at, catalog_hash,
|
|
30
|
+
node_type, width, height, layer_count, complexity_band, complexity_fill,
|
|
31
|
+
colors_json, instance_total, deprecated_used, identity_json
|
|
32
|
+
) VALUES (
|
|
33
|
+
${n.id},
|
|
34
|
+
(SELECT COALESCE(MAX(ordinal), 0) + 1 FROM scans),
|
|
35
|
+
${n.nodeId}, ${n.name}, ${n.importedAtIso}, ${t.catalogHash},
|
|
36
|
+
${n.nodeType}, ${n.width}, ${n.height}, ${n.layerCount},
|
|
37
|
+
${n.complexityBand}, ${n.complexityFilled},
|
|
38
|
+
${JSON.stringify(n.colors)}, ${n.instanceTotal}, ${n.deprecatedUsed},
|
|
39
|
+
${JSON.stringify(n.identity)}
|
|
40
|
+
)
|
|
41
|
+
`},v=t=>{let n=t.summary;return e`
|
|
42
|
+
UPDATE scans SET
|
|
43
|
+
node_id = ${n.nodeId}, name = ${n.name}, catalog_hash = ${t.catalogHash},
|
|
44
|
+
node_type = ${n.nodeType}, width = ${n.width}, height = ${n.height},
|
|
45
|
+
layer_count = ${n.layerCount}, complexity_band = ${n.complexityBand},
|
|
46
|
+
complexity_fill = ${n.complexityFilled}, colors_json = ${JSON.stringify(n.colors)},
|
|
47
|
+
instance_total = ${n.instanceTotal}, deprecated_used = ${n.deprecatedUsed},
|
|
48
|
+
identity_json = ${JSON.stringify(n.identity)}
|
|
49
|
+
WHERE dsl_hash = ${n.id}
|
|
50
|
+
`},y=t=>O.gen(function*(){yield*e`DELETE FROM scans WHERE dsl_hash = ${t}`,yield*e`DELETE FROM group_by_card WHERE card_id = ${t}`,yield*e`DELETE FROM recents WHERE card_id = ${t}`}),b=t=>O.gen(function*(){yield*e`DELETE FROM recents`;for(let[n,r]of t.entries())yield*e`INSERT INTO recents (card_id, ordinal) VALUES (${r}, ${n})`}),x=(t,n)=>e`
|
|
51
|
+
INSERT INTO panel (k, v) VALUES (${t}, ${n})
|
|
52
|
+
ON CONFLICT(k) DO UPDATE SET v = excluded.v
|
|
53
|
+
`,S=(e,t)=>x(e,t?`1`:`0`);return{listScans:t,getScan:n,getAnyScan:r,scanCount:i,findByNodeId:a,readGalleryState:l,readPanelJson:u,catalogIsReferenced:f,rawEvictionCandidates:p,rawKeepWindow:m,catalogEvictionCandidates:h,catalogKeepWindow:g,newestCatalogImport:t=>e`
|
|
54
|
+
SELECT imported_at FROM scans
|
|
55
|
+
WHERE catalog_hash = ${t} AND deleted = 0
|
|
56
|
+
ORDER BY imported_at DESC LIMIT 1
|
|
57
|
+
`.pipe(O.map(e=>e[0]===void 0?null:X(e[0].imported_at)),O.orDie),insertScan:_,updateScanSummary:v,deleteScan:y,markDeleted:o,listDeleted:s,hardDeleteScan:c,setRecents:b,setPanelJson:x,clearRemoteSetup:()=>e`DELETE FROM panel WHERE k = ${it}`,writeGalleryState:(t,n)=>O.gen(function*(){yield*e`DELETE FROM groups`;for(let[t,r]of n.groups.entries())yield*e`
|
|
58
|
+
INSERT INTO groups (id, name, ordinal, pinned, collapsed)
|
|
59
|
+
VALUES (${r.id}, ${r.name}, ${t},
|
|
60
|
+
${r.pinned?1:0}, ${r.collapsed?1:0})
|
|
61
|
+
`;for(let r of Object.keys(t.groupByCardId))n.groupByCardId[r]===void 0&&(yield*e`DELETE FROM group_by_card WHERE card_id = ${r}`);for(let[r,i]of Object.entries(n.groupByCardId))t.groupByCardId[r]!==i&&(yield*e`
|
|
62
|
+
INSERT INTO group_by_card (card_id, group_id) VALUES (${r}, ${i})
|
|
63
|
+
ON CONFLICT(card_id) DO UPDATE SET group_id = excluded.group_id
|
|
64
|
+
`);t.unsortedPinned!==n.unsortedPinned&&(yield*S($e,n.unsortedPinned)),t.unsortedCollapsed!==n.unsortedCollapsed&&(yield*S(et,n.unsortedCollapsed)),t.recents.join(`\0`)!==n.recents.join(`\0`)&&(yield*b(n.recents))}),transaction:e.withTransaction}},ct=e=>({catalogHash:ot(e.catalog_hash),summary:{id:X(e.dsl_hash),nodeId:X(e.node_id),name:X(e.name),importedAtIso:X(e.imported_at),nodeType:X(e.node_type),width:Z(e.width),height:Z(e.height),layerCount:Z(e.layer_count),complexityBand:X(e.complexity_band),complexityFilled:Z(e.complexity_fill),colors:JSON.parse(X(e.colors_json)),instanceTotal:Z(e.instance_total),deprecatedUsed:Z(e.deprecated_used),identity:JSON.parse(X(e.identity_json)),previewSvg:``}}),lt=c.decodeEffect(c.fromJsonString(a)),ut=c.decodeEffect(c.fromJsonString(r)),dt=c.encodeEffect(c.fromJsonString(a)),ft=/^[0-9a-f]{64}$/,pt=/-[0-9a-f]{64}$/,mt=/^[0-9a-f]{64}\.json$/,ht=[`dsl.raw`,`card.json`,`summary.json`,`preview.png`,`nodes.json`],gt=40,_t=256*1024*1024,vt=20,yt=64*1024*1024,bt=(e,t)=>e.id===t.id&&e.nodeId===t.nodeId&&e.name===t.name&&e.nodeType===t.nodeType&&e.importedAtIso===t.importedAtIso&&e.instanceTotal===t.instanceTotal&&e.deprecatedUsed===t.deprecatedUsed&&e.identity.componentName===t.identity.componentName&&e.identity.library===t.identity.library&&e.identity.deprecated===t.identity.deprecated,xt=(e,t)=>O.gen(function*(){let n=yield*H.FileSystem,r=yield*A.Path,i=yield*V.currentTimeMillis,a=!1,o=0,s=(e,s)=>O.gen(function*(){yield*n.makeDirectory(t.paths.quarantineDir,{recursive:!0}).pipe(O.andThen(n.rename(r.join(t.paths.scansDir,e),r.join(t.paths.quarantineDir,`${i}-${e}`))),O.orElseSucceed(()=>void 0)),a=!0,o+=1,yield*O.logError(`[pixso] store: scan dir quarantined — this card is NOT in the gallery any more`,{dirName:e,reason:s})}),c=yield*e.listScans(),l=e=>O.gen(function*(){let n=e.summary.id,r=yield*t.readSummary(n).pipe(O.orElseSucceed(()=>null));if(r!==null){let e=yield*lt(r).pipe(O.orElseSucceed(()=>null));if(e!==null&&e.id===n)return!0}let i=yield*t.readCardOrNull(n);if(i===null)return(yield*t.scanDirExists(n))&&(yield*s(n,`indexed dir has no card.json`)),!1;let a=yield*ut(i).pipe(O.orElseSucceed(()=>null));return a===null||a.id!==n?(yield*s(n,a===null?`card.json does not decode`:`card.json carries a foreign id`),!1):(yield*dt(fe(a)).pipe(O.flatMap(e=>t.writeSummary(n,e)),O.orElseSucceed(()=>void 0)),!0)}),u=[];for(let e of c)(yield*l(e))||u.push(e.summary.id);u.length>0&&(yield*e.transaction(O.forEach(u,t=>e.deleteScan(t),{discard:!0})));let d=yield*t.listScanDirs(),f=new Set((yield*e.listScans()).map(e=>e.summary.id)),p=new Set(yield*e.listDeleted()),m=[];for(let e of d){if(f.has(e)||p.has(e))continue;if(!ft.test(e)){yield*s(e,`unindexed entry name is not a content hash`);continue}let n=yield*t.statScanDir(e);if(n===null)continue;if(n.type!==`Directory`){yield*s(e,`scan entry is not a directory`);continue}let r=yield*t.readCardOrNull(e);if(r===null){yield*s(e,`unindexed dir has no card.json`);continue}let i=yield*ut(r).pipe(O.orElseSucceed(()=>null));if(i===null||i.id!==e){yield*s(e,i===null?`card.json does not decode`:`card.json carries a foreign id`);continue}let a=yield*t.readSummaryOrNull(e).pipe(O.flatMap(t=>t===null?O.succeed(null):lt(t).pipe(O.flatMap(t=>t.id===e?O.succeed(t):O.succeed(null)),O.orElseSucceed(()=>null)))),o=a??fe(i);a===null&&(yield*dt(o).pipe(O.flatMap(n=>t.writeSummary(e,n)),O.orElseSucceed(()=>void 0))),m.push({card:i,summary:o})}m.length>0&&(m.sort((e,t)=>e.card.importedAtIso.localeCompare(t.card.importedAtIso)),yield*e.transaction(O.forEach(m,({card:t,summary:n})=>e.insertScan({summary:{...n,previewSvg:``},catalogHash:t.catalogHash}),{discard:!0}))),o>0&&(yield*O.logError(`[pixso] store: cards were quarantined — the gallery is SHORTER than the store was`,{quarantined:o,served:yield*e.scanCount()})),yield*Ot(e,t),a?yield*O.logError(`[pixso] store: the load could not describe everything on disk — EVERY destructive pass skipped`,{served:yield*e.scanCount()}):(yield*St(e,t),yield*Ct(t),yield*Et(t),yield*jt(e,t,{dslHash:null,catalogHash:null})),yield*O.logDebug(`[pixso] store loaded`,{scans:yield*e.scanCount(),dropped:u.length,adopted:m.length,quarantined:o})}),St=(e,t)=>O.gen(function*(){let n=yield*H.FileSystem,r=yield*A.Path,i=yield*e.listScans(),a=new Set(i.flatMap(e=>e.catalogHash===null?[]:[e.catalogHash])),o=yield*t.listCatalogEntries();for(let e of o)mt.test(e)&&a.has(e.slice(0,-5))||(yield*n.remove(r.join(t.paths.catalogsDir,e),{recursive:!0,force:!0}).pipe(O.orElseSucceed(()=>void 0)))}),Ct=e=>O.gen(function*(){let t=yield*H.FileSystem,n=yield*A.Path,r=e=>t.stat(e).pipe(O.map(e=>e.type===`Directory`),O.orElseSucceed(()=>!1)),i=yield*e.listScanDirs();for(let a of i){if(!ft.test(a))continue;let i=yield*e.listScanDirEntries(a);for(let o of i){if(!ht.some(e=>Pe(o,e)))continue;let i=n.join(e.paths.scanDir(a),o);(yield*r(i))&&(yield*t.remove(i,{recursive:!0,force:!0}).pipe(O.orElseSucceed(()=>void 0)))}}}),wt=e=>{let t=/^(\d+)-/.exec(e);return t===null?0:Number(t[1])},Tt=e=>pt.test(e),Et=e=>O.gen(function*(){let t=yield*e.listQuarantineEntries();if(t.length<=10)return;let n=[...t].sort((e,t)=>{let n=wt(e)-wt(t);if(n!==0)return n;let r=Tt(e);return r===Tt(t)?e.localeCompare(t):r?1:-1}).slice(0,t.length-10);for(let t of n)yield*e.removeQuarantineEntry(t)}),Dt=(e,t,n,r,i)=>O.gen(function*(){yield*e.transaction(e.markDeleted(r)),n?.previews.delete(r),n?.withImage.delete(r),(yield*t.removeScanDir(r).pipe(O.as(!0),O.orElseSucceed(()=>!1)))?yield*e.transaction(e.hardDeleteScan(r)):yield*O.logDebug(`[pixso] store: scan dir survived a delete — the tombstone holds until the next retry`,{id:r}),i!==null&&((yield*e.catalogIsReferenced(i))||(yield*t.removeCatalog(i).pipe(O.orElseSucceed(()=>void 0))))}),Ot=(e,t,n=null)=>O.gen(function*(){let r=yield*e.listDeleted();for(let i of r)yield*Dt(e,t,n,i,(yield*e.getAnyScan(i))?.catalogHash??null)}),kt=(e,t)=>{let n=[],r=0;for(let i of e)if(i.bytes!==null){if(r>0&&r+i.bytes>t){n.push(i.hash);continue}r+=i.bytes}return n},At=(e,t,n)=>O.forEach(e,e=>n(e).pipe(O.map(t=>({hash:e,bytes:t})))).pipe(O.map(e=>kt(e,t))),jt=(e,t,n)=>O.gen(function*(){let r=e=>t.removeDsl(e).pipe(O.catch(t=>O.logDebug(`[pixso] store: evicted raw could not be removed`,{hash:e,cause:String(t)}))),i=e=>t.removeCatalog(e).pipe(O.catch(t=>O.logDebug(`[pixso] store: evicted catalog could not be removed`,{hash:e,cause:String(t)})));for(let t of yield*e.rawEvictionCandidates(40,n.dslHash))yield*r(t);let a=yield*e.rawKeepWindow(40,n.dslHash);for(let e of yield*At(a,_t,e=>t.dslBytes(e).pipe(O.orElseSucceed(()=>null))))yield*r(e);for(let t of yield*e.catalogEvictionCandidates(20,n.catalogHash))yield*i(t);let o=yield*e.catalogKeepWindow(20,n.catalogHash);for(let e of yield*At(o,yt,e=>t.catalogBytes(e).pipe(O.orElseSucceed(()=>null))))yield*i(e)}),Mt=O.gen(function*(){let e=yield*ge.SqlClient;yield*e`
|
|
65
|
+
CREATE TABLE IF NOT EXISTS scans (
|
|
66
|
+
dsl_hash TEXT PRIMARY KEY,
|
|
67
|
+
ordinal INTEGER NOT NULL,
|
|
68
|
+
node_id TEXT NOT NULL,
|
|
69
|
+
name TEXT NOT NULL,
|
|
70
|
+
imported_at TEXT NOT NULL,
|
|
71
|
+
catalog_hash TEXT,
|
|
72
|
+
node_type TEXT NOT NULL,
|
|
73
|
+
width REAL NOT NULL,
|
|
74
|
+
height REAL NOT NULL,
|
|
75
|
+
layer_count INTEGER NOT NULL,
|
|
76
|
+
complexity_band TEXT NOT NULL,
|
|
77
|
+
complexity_fill REAL NOT NULL,
|
|
78
|
+
colors_json TEXT NOT NULL,
|
|
79
|
+
instance_total INTEGER NOT NULL,
|
|
80
|
+
deprecated_used INTEGER NOT NULL,
|
|
81
|
+
identity_json TEXT NOT NULL
|
|
82
|
+
)
|
|
83
|
+
`,yield*e`CREATE UNIQUE INDEX IF NOT EXISTS scans_ordinal ON scans(ordinal)`,yield*e`CREATE INDEX IF NOT EXISTS scans_node_id ON scans(node_id, imported_at)`,yield*e`CREATE INDEX IF NOT EXISTS scans_catalog ON scans(catalog_hash)`,yield*e`
|
|
84
|
+
CREATE TABLE IF NOT EXISTS groups (
|
|
85
|
+
id TEXT PRIMARY KEY,
|
|
86
|
+
name TEXT NOT NULL,
|
|
87
|
+
ordinal INTEGER NOT NULL,
|
|
88
|
+
pinned INTEGER NOT NULL,
|
|
89
|
+
collapsed INTEGER NOT NULL
|
|
90
|
+
)
|
|
91
|
+
`,yield*e`CREATE UNIQUE INDEX IF NOT EXISTS groups_ordinal ON groups(ordinal)`,yield*e`
|
|
92
|
+
CREATE TABLE IF NOT EXISTS group_by_card (
|
|
93
|
+
card_id TEXT PRIMARY KEY,
|
|
94
|
+
group_id TEXT NOT NULL
|
|
95
|
+
)
|
|
96
|
+
`,yield*e`
|
|
97
|
+
CREATE TABLE IF NOT EXISTS recents (
|
|
98
|
+
card_id TEXT PRIMARY KEY,
|
|
99
|
+
ordinal INTEGER NOT NULL
|
|
100
|
+
)
|
|
101
|
+
`,yield*e`
|
|
102
|
+
CREATE TABLE IF NOT EXISTS panel (
|
|
103
|
+
k TEXT PRIMARY KEY,
|
|
104
|
+
v TEXT NOT NULL
|
|
105
|
+
)
|
|
106
|
+
`}),Nt=O.gen(function*(){let e=yield*ge.SqlClient;(yield*e`PRAGMA table_info(scans)`).some(e=>e.name===`deleted`)||(yield*e`ALTER TABLE scans ADD COLUMN deleted INTEGER NOT NULL DEFAULT 0`)}),Pt=[[1,`IndexTables`,Mt],[2,`SoftDelete`,Nt]];let Ft=null;const It={derive:()=>(Ft??=G.scryptSync(`pixso-remote-token`,`${ye.userInfo().username}-pixso-remote-token`,32),Ft)};function Lt(e,t=It){let n=G.randomBytes(12),r=G.createCipheriv(`aes-256-gcm`,t.derive(),n),i=Buffer.concat([r.update(e,`utf8`),r.final()]),a=r.getAuthTag();return`${n.toString(`hex`)}:${a.toString(`hex`)}:${i.toString(`hex`)}`}function Rt(e){return/^[0-9a-f]{24}:[0-9a-f]{32}:[0-9a-f]*$/i.test(e)}function zt(e,t=It){let n=e.split(`:`);if(n.length!==3)throw Error(`malformed token blob`);let[r,i,a]=n,o=G.createDecipheriv(`aes-256-gcm`,t.derive(),Buffer.from(r??``,`hex`));return o.setAuthTag(Buffer.from(i??``,`hex`)),Buffer.concat([o.update(Buffer.from(a??``,`hex`)),o.final()]).toString(`utf8`)}const Bt=c.encodeEffect(c.fromJsonString(r)),Vt=c.encodeEffect(c.fromJsonString(a)),Ht=c.is(e),Ut=t=>new e({detail:`${l(`Scan store operation failed`,`Операция хранилища сканов не удалась`)}: ${t}`}),Q=e=>t=>t.pipe(O.tapError(t=>Ht(t)?O.void:O.logError(`[pixso] store operation failed`,{operation:e,cause:String(t)})),O.mapError(t=>Ht(t)?t:Ut(e))),$=t=>t.pipe(O.tapError(e=>O.logError(`[pixso] store encode failed`,{cause:String(e)})),O.mapError(()=>new e({detail:l(`Storage encode failed — see the server log.`,`Ошибка кодирования хранилища — смотрите лог сервера.`)}))),Wt=(e,t)=>[t,...e.filter(e=>e!==t)].slice(0,2);var Gt=class extends D.Service()(`@smart-tools/t3-code-pixso-mcp-assistant/server/store/ScanStore`){};function Kt(e,t){return e===void 0||e.fetched.length!==t.fetched.length||e.failed.length!==t.failed.length?!1:e.fetched.every((e,n)=>e===t.fetched[n])&&e.failed.every((e,n)=>e.guid===t.failed[n].guid&&e.message===t.failed[n].message)}const qt=O.gen(function*(){let a=yield*Oe,u=yield*O.serviceOption(ke).pipe(O.map(W.getOrUndefined)),d=yield*H.FileSystem,f=yield*A.Path,p=Ve(f,a.rootDir),m=e=>e.pipe(O.provideService(H.FileSystem,d),O.provideService(A.Path,f)),h=yield*U.make(1),g=yield*U.make(1),_=yield*j.make(W.none()),v=()=>u===void 0?O.gen(function*(){let{DatabaseSync:e}=yield*O.promise(()=>import(`node:sqlite`)),t=new e(f.join(a.rootDir,`index.db`)),n=yield*O.promise(()=>import(`effect/unstable/reactivity/Reactivity`)),r=yield*O.promise(()=>import(`effect/unstable/sql/Statement`)),i=yield*U.make(1),o={execute:(e,n,r)=>{let i=t.prepare(e),a=i.columns().length>0?i.all(...n):(i.run(...n),[]);return O.succeed(r?r(a):a)},executeRaw:(e,n)=>{let r=t.prepare(e),i=r.columns().length>0;return O.succeed(i?r.all(...n):r.run(...n))},executeUnprepared:(e,n,r)=>{let i=t.prepare(e),a=i.columns().length>0?i.all(...n):(i.run(...n),[]);return O.succeed(r?r(a):a)},executeValues:(e,n)=>{let r=t.prepare(e);return r.columns().length?(r.setReturnArrays(!0),O.succeed(r.all(...n))):(r.run(...n),O.succeed([]))},executeStream:()=>{throw Error(`executeStream not supported`)}},s=i.withPermits(1)(O.succeed(o)),c=i.withPermits(1)(O.succeed(o));return yield*ge.make({acquirer:s,transactionAcquirer:c,compiler:r.makeCompilerSqlite(),spanAttributes:[]}).pipe(O.provide(n.layer))}).pipe(Q(`open database`)):O.succeed(u),y=()=>{let e=g.withPermits(1)(j.get(_).pipe(O.flatMap(W.match({onNone:()=>O.gen(function*(){let e=yield*v(),t=st(e);for(let[,,t]of Pt)yield*t.pipe(O.provideService(ge.SqlClient,e),O.orDie);let n=He(p);yield*m(xt(t,n)).pipe(Q(`load`));let r=new Map,i=new Set,a=yield*t.listScans();yield*O.forEach(a,e=>O.gen(function*(){yield*m(n.readSummaryOrNull(e.summary.id)).pipe(O.map(t=>{if(t!==null)try{let n=JSON.parse(t);typeof n.previewSvg==`string`&&n.previewSvg!==``&&r.set(e.summary.id,n.previewSvg)}catch{}}),O.orElseSucceed(()=>void 0)),(yield*m(n.imageExists(e.summary.id)).pipe(O.orElseSucceed(()=>!1)))&&i.add(e.summary.id)}),{concurrency:16});let o={indexDb:t,blobs:n,previews:r,withImage:i};return yield*j.set(_,W.some(o)),o}),onSome:O.succeed}))));return j.get(_).pipe(O.flatMap(W.match({onNone:()=>e,onSome:O.succeed})))},b=c.decodeEffect(c.fromJsonString(r)),x=c.decodeEffect(c.fromJsonString(i)),S=c.decodeEffect(c.fromJsonString(n)),C=c.decodeEffect(c.fromJsonString(o)),w=c.encodeEffect(c.fromJsonString(i)),T=c.decodeEffect(c.fromJsonString(t)),E=c.encodeEffect(c.fromJsonString(t)),ee=c.encodeEffect(c.fromJsonString(n)),D=c.encodeEffect(c.fromJsonString(o)),k=c.decodeEffect(c.fromJsonString(c.String)),te=c.encodeEffect(c.fromJsonString(c.String)),M=c.decodeEffect(c.fromJsonString(c.Boolean)),N=c.encodeEffect(c.fromJsonString(c.Boolean)),P=()=>O.gen(function*(){let{indexDb:e,previews:t,withImage:n}=yield*y(),r=yield*e.listScans(),i=yield*e.readGalleryState(),a=yield*e.readPanelJson(Y),o=yield*e.readPanelJson(tt),s=yield*e.readPanelJson(nt),c=yield*e.readPanelJson(it),l=yield*e.readPanelJson(rt),u=r.map(e=>({...e.summary,previewSvg:t.get(e.summary.id)??``,imageAvailable:n.has(e.summary.id)})),d=a===null?null:yield*x(a),f=s===null?null:yield*S(s),p=o===null?null:yield*C(o);return{cards:u,groups:i.groups,groupByCardId:i.groupByCardId,unsortedPinned:i.unsortedPinned,unsortedCollapsed:i.unsortedCollapsed,recents:i.recents,lastCheck:f,lastProbe:p,lastScanAtIso:d?.atIso??null,supportsReparse:!0,supportsRemote:!0,remoteTokenSet:c!==null,remoteByDefault:l===null?!0:yield*M(l)}}).pipe(Q(`get snapshot`)),F=t=>O.gen(function*(){let{indexDb:n,blobs:r}=yield*y(),i=yield*n.getScan(t);if(i===null)return yield*new e({detail:l(`The card was not found.`,`Карточка не найдена.`)});let a=yield*b(yield*m(r.readCard(t))),o=yield*m(r.dslExists(t)),s=yield*m(r.imageExists(t));return{...a,importedAtIso:i.summary.importedAtIso,catalogHash:i.catalogHash,rawAvailable:o,imageAvailable:s}}).pipe(Q(`read card`)),I=t=>O.gen(function*(){let{indexDb:n,blobs:r}=yield*y();return(yield*n.getScan(t))===null?yield*new e({detail:l(`The card was not found.`,`Карточка не найдена.`)}):(yield*m(r.dslExists(t)))?yield*m(r.readDsl(t)):yield*new e({detail:l(`The raw DSL of this card was rotated out by storage retention.`,`Сырой DSL этой карточки вытеснен ротацией хранилища.`)})}).pipe(Q(`read dsl`)),ne=t=>O.gen(function*(){let{indexDb:n,blobs:r}=yield*y();if((yield*n.getScan(t))===null)return yield*new e({detail:l(`The card was not found.`,`Карточка не найдена.`)});let i=yield*m(r.readImageOrNull(t));return i===null?yield*new e({detail:l(`This card has no preview image.`,`У этой карточки нет изображения предпросмотра.`)}):B.Buffer.from(i).toString(`base64`)}).pipe(Q(`read image`)),L=t=>O.gen(function*(){let{indexDb:n,blobs:r}=yield*y(),i=yield*n.newestCatalogImport(t);if(i===null)return yield*new e({detail:l(`The catalog was not found.`,`Каталог не найден.`)});let a=yield*m(r.readCatalogOrNull(t));return a===null?yield*new e({detail:l(`The catalog snapshot was rotated out by storage retention.`,`Снимок каталога вытеснен ротацией хранилища.`)}):{raw:a,capturedAtIso:i}}).pipe(Q(`read catalog`)),re=e=>O.gen(function*(){let{indexDb:t}=yield*y();return yield*t.findByNodeId(e)}).pipe(Q(`find scan by node id`)),R=e=>O.gen(function*(){let{blobs:t}=yield*y(),n=yield*m(t.readNodesOrNull(e));return n===null?null:yield*T(n).pipe(O.orElseSucceed(()=>null))}).pipe(Q(`read resolved nodes`)),ie=()=>O.gen(function*(){let{indexDb:e}=yield*y(),t=yield*e.readPanelJson(Y);return t===null?null:yield*x(t)}).pipe(Q(`get latest report`)),ae=(e,t,n)=>m(Dt(e.indexDb,e.blobs,e,t,n));return{getSnapshot:P,getCard:F,getCardRaw:I,getCardImage:ne,getCatalogRaw:L,findScanByNodeId:re,getResolvedNodes:R,removeCard:t=>h.withPermits(1)(O.gen(function*(){let n=yield*y(),r=yield*n.indexDb.getScan(t);if(r===null)return yield*new e({detail:l(`The card was not found.`,`Карточка не найдена.`)});yield*ae(n,t,r.catalogHash)}).pipe(Q(`remove card`))),mutateGallery:e=>h.withPermits(1)(O.gen(function*(){let t=yield*y(),{indexDb:n}=t,r=yield*n.readGalleryState(),i=s({groups:r.groups,groupByCardId:r.groupByCardId,unsortedPinned:r.unsortedPinned,unsortedCollapsed:r.unsortedCollapsed},e),a=r,o={...i.state,recents:r.recents},c=yield*O.forEach(i.removedCardIds,e=>n.getScan(e).pipe(O.map(t=>({cardId:e,catalogHash:t?.catalogHash??null}))));yield*n.transaction(n.writeGalleryState(a,o));for(let{cardId:e,catalogHash:n}of c)yield*ae(t,e,n)}).pipe(Q(`mutate gallery`))),getLatestReport:ie,persistScan:(e,t)=>h.withPermits(1)(O.gen(function*(){let n=yield*y(),{indexDb:r,blobs:i,previews:a,withImage:o}=n,s=Qe(e.dslRaw),c=e.catalogRaw===null?null:Qe(e.catalogRaw),l=yield*r.getScan(s);if(l===null){let e=yield*r.getAnyScan(s);e!==null&&(yield*ae(n,s,e.catalogHash))}let u=t=>O.gen(function*(){let n=e.imagePngBase64;if(n==null||n===``)return!1;if(yield*m(i.imageExists(t)))return o.add(t),!1;let r=B.Buffer.from(n,`base64`);return r.length===0?!1:(yield*m(i.writeImage(t,new Uint8Array(r))),o.add(t),!0)}).pipe(O.catchCause(e=>O.logDebug(`[pixso] store: preview image could not be saved`,{id:t,cause:String(e)}).pipe(O.as(!1)))),d=e.resolvedNodes===void 0?null:ue(e.resolvedNodes),f=t=>e.resolvedNodes===void 0?O.void:O.gen(function*(){let n=yield*$(E(e.resolvedNodes));yield*m(i.writeNodes(t,n))}),p=e.provenance===void 0?null:{source:e.provenance.source,fileKey:e.provenance.fileKey,guid:e.summary.nodeId,designUrl:e.provenance.designUrl,importedAtIso:e.capturedAtIso};if(l!==null){let o=l.summary.importedAtIso;(yield*m(i.dslExists(s)))||(yield*m(i.writeDsl(s,e.dslRaw))),e.catalogRaw!==null&&c!==null&&(yield*m(i.writeCatalog(c,e.catalogRaw)));let h=yield*u(s);yield*f(s);let g=p===null?null:yield*m(i.readCard(s)).pipe(O.flatMap(b),O.map(e=>({...e,importedAtIso:o,catalogHash:l.catalogHash})),O.orElseSucceed(()=>null)),_=g===null||p===null?null:qe(Je(g),p),v=c===null||c===l.catalogHash?null:{catalogHash:c,card:{...e.card,id:s,importedAtIso:o,catalogHash:c,..._===null?{}:{provenances:_},...d===null?{}:{resolvedNodes:d}},summary:{...e.summary,id:s,importedAtIso:o}};if(v!==null)yield*m(i.writeCard(s,yield*$(Bt(v.card)))),yield*m(i.writeSummary(s,yield*$(Vt(v.summary))));else if(g!==null){let e=_!==null&&(g.provenances===void 0||g.provenances.length!==_.length),t=d!==null&&!Kt(g.resolvedNodes,d);(e||t)&&(yield*m(i.writeCard(s,yield*$(Bt({...g,..._===null?{}:{provenances:_},...d===null?{}:{resolvedNodes:d}})))))}let y=Wt(yield*r.readGalleryState().pipe(O.map(e=>e.recents)),s),x=l.catalogHash;yield*r.transaction(O.gen(function*(){v!==null&&(yield*r.updateScanSummary({summary:v.summary,catalogHash:v.catalogHash})),yield*r.setRecents(y),yield*r.setPanelJson(Y,yield*w({atIso:e.capturedAtIso,data:{...e.report,outcome:`reimport`,duplicate:!0},origin:e.origin}))})),v!==null&&v.summary.previewSvg&&a.set(s,v.summary.previewSvg);let S=l.catalogHash===null&&v!==null&&v.catalogHash!==null,C=[...h?[`image`]:[],...S?[`components`]:[]];return t!==void 0&&(yield*t({id:s,duplicate:!0,enriched:C})),v!==null&&x!==null&&x!==v.catalogHash&&((yield*r.catalogIsReferenced(x))||(yield*m(i.removeCatalog(x)).pipe(O.orElseSucceed(()=>void 0)))),yield*m(Ot(r,i,n)).pipe(O.orElseSucceed(()=>void 0)),yield*m(jt(r,i,{dslHash:s,catalogHash:c})).pipe(O.orElseSucceed(()=>void 0)),{id:s,duplicate:!0,enriched:C}}if(p!==null&&e.provenance!==void 0){let a=yield*r.findByNodeId(e.summary.nodeId),o=a===null?null:yield*r.getScan(a),s=a===null||o===null?null:yield*m(i.readCard(a)).pipe(O.flatMap(b),O.map(e=>({...e,importedAtIso:o.summary.importedAtIso,catalogHash:o.catalogHash})),O.orElseSucceed(()=>null)),l=s!==null&&!Je(s).some(t=>t.source===e.provenance?.source);if(a!==null&&o!==null&&s!==null&&l&&Xe(s,e.provenance.fileKey)){let l=o.summary.importedAtIso,h=o.catalogHash===null&&c!==null;h&&e.catalogRaw!==null&&c!==null&&(yield*m(i.writeCatalog(c,e.catalogRaw)));let g=yield*u(a);yield*f(a);let _=o.catalogHash??c,v={...Ze({existing:s,incoming:e.card,incomingProvenance:p}),id:a,importedAtIso:l,catalogHash:_,...d===null?{}:{resolvedNodes:d}};yield*m(i.writeCard(a,yield*$(Bt(v))));let y=Wt(yield*r.readGalleryState().pipe(O.map(e=>e.recents)),a);yield*r.transaction(O.gen(function*(){_!==o.catalogHash&&(yield*r.updateScanSummary({summary:o.summary,catalogHash:_})),yield*r.setRecents(y),yield*r.setPanelJson(Y,yield*w({atIso:e.capturedAtIso,data:{...e.report,outcome:`reimport`,duplicate:!0},origin:e.origin}))}));let b=[...g?[`image`]:[],...h?[`components`]:[]];return t!==void 0&&(yield*t({id:a,duplicate:!0,enriched:b})),yield*m(Ot(r,i,n)).pipe(O.orElseSucceed(()=>void 0)),yield*m(jt(r,i,{dslHash:a,catalogHash:_})).pipe(O.orElseSucceed(()=>void 0)),{id:a,duplicate:!0,enriched:b}}}let h={...e.card,id:s,importedAtIso:e.capturedAtIso,catalogHash:c,...p===null?{}:{provenances:[p]},...d===null?{}:{resolvedNodes:d}},g={...e.summary,id:s,importedAtIso:e.capturedAtIso};yield*m(i.ensureScanDir(s)),yield*m(i.writeDsl(s,e.dslRaw)),yield*f(s),yield*m(i.writeCard(s,yield*$(Bt(h)))),yield*m(i.writeSummary(s,yield*$(Vt(g)))),e.catalogRaw!==null&&c!==null&&(yield*m(i.writeCatalog(c,e.catalogRaw))),yield*u(s);let _=Wt(yield*r.readGalleryState().pipe(O.map(e=>e.recents)),s),v={summary:g,catalogHash:c};return yield*r.transaction(O.gen(function*(){yield*r.insertScan(v),yield*r.setRecents(_),yield*r.setPanelJson(Y,yield*w({atIso:e.capturedAtIso,data:e.report,origin:e.origin}))})),g.previewSvg&&a.set(s,g.previewSvg),t!==void 0&&(yield*t({id:s,duplicate:!1,enriched:[]})),yield*m(Ot(r,i,n)).pipe(O.orElseSucceed(()=>void 0)),yield*m(jt(r,i,{dslHash:s,catalogHash:c})).pipe(O.orElseSucceed(()=>void 0)),{id:s,duplicate:!1,enriched:[]}}).pipe(Q(`persist scan`))),recordReport:e=>h.withPermits(1)(O.gen(function*(){let{indexDb:t}=yield*y(),n=yield*w(e);yield*t.transaction(t.setPanelJson(Y,n))}).pipe(Q(`record report`))),recordCheck:e=>h.withPermits(1)(O.gen(function*(){let{indexDb:t}=yield*y(),n=yield*ee(e);yield*t.transaction(t.setPanelJson(nt,n))}).pipe(Q(`record check`))),recordProbe:e=>h.withPermits(1)(O.gen(function*(){let{indexDb:t}=yield*y(),n=yield*D(e);yield*t.transaction(t.setPanelJson(tt,n))}).pipe(Q(`record probe`))),reparseScans:e=>h.withPermits(1)(O.gen(function*(){let{indexDb:t,blobs:n}=yield*y(),r=(yield*t.listScans()).map(e=>e.summary.id),i=0,a=0,o=0,s=0;for(let c of r){let r=yield*t.getScan(c);if(r===null)continue;let l=yield*m(n.readDslOrNull(c));if(l===null){a+=1;continue}let u=r.catalogHash===null?null:yield*m(n.readCatalogOrNull(r.catalogHash));if(r.catalogHash!==null&&u===null){o+=1;continue}let d=yield*m(n.readNodesOrNull(c)),f=d===null?null:yield*T(d).pipe(O.orElseSucceed(()=>null)),p=e({dslRaw:l,catalogRaw:u,rootGuid:r.summary.nodeId,resolvedNodes:f});if(p===null){s+=1;continue}let h=yield*m(n.readCard(c)).pipe(O.flatMap(b),O.orElseSucceed(()=>null)),g=/^\s*\{\s*"dsl"\s*:/.test(l)?`remote`:`local`,_=h?.source??g,v=h?.provenances!==void 0&&h.provenances.length>0?h.provenances:[{source:_??`local`,fileKey:null,guid:r.summary.nodeId,designUrl:null,importedAtIso:r.summary.importedAtIso}],y={...p.card,id:c,importedAtIso:r.summary.importedAtIso,catalogHash:r.catalogHash,source:_,provenances:v,...h?.resolvedNodes===void 0?{}:{resolvedNodes:h.resolvedNodes}},x={...p.summary,id:c,importedAtIso:r.summary.importedAtIso};yield*m(n.writeCard(c,yield*$(Bt(y)))),yield*m(n.writeSummary(c,yield*$(Vt(x)))),yield*t.transaction(t.updateScanSummary({summary:x,catalogHash:r.catalogHash})),i+=1}return{total:r.length,reparsed:i,skippedNoRaw:a,skippedNoCatalog:o,failed:s}}).pipe(Q(`reparse`))),getRemoteToken:()=>O.gen(function*(){let{indexDb:e}=yield*y(),t=yield*e.readPanelJson(it);if(t===null)return null;let n=yield*k(t);if(!Rt(n)){let t=Lt(n);return yield*h.withPermits(1)(O.gen(function*(){let n=yield*te(t);yield*e.transaction(e.setPanelJson(it,n))})),n}return yield*O.try({try:()=>zt(n),catch:()=>Ut(`decrypt remote token`)})}).pipe(Q(`get remote token`)),setRemoteToken:e=>h.withPermits(1)(O.gen(function*(){let{indexDb:t}=yield*y(),n=yield*te(Lt(e));yield*t.transaction(t.setPanelJson(it,n))}).pipe(Q(`save remote token`))),clearRemoteToken:()=>h.withPermits(1)(O.gen(function*(){let{indexDb:e}=yield*y();yield*e.transaction(e.clearRemoteSetup())}).pipe(Q(`delete remote token`))),getRemoteByDefault:()=>O.gen(function*(){let{indexDb:e}=yield*y(),t=yield*e.readPanelJson(rt);return t===null?!0:yield*M(t)}).pipe(Q(`get remote mode`)),setRemoteByDefault:e=>h.withPermits(1)(O.gen(function*(){let{indexDb:t}=yield*y(),n=yield*N(e);yield*t.transaction(t.setPanelJson(rt,n))}).pipe(Q(`set remote mode`))),diagnosticsDir:p.diagnosticsDir}}),Jt=k.effect(Gt,qt);var Yt=class extends D.Service()(`@smart-tools/t3-code-pixso-mcp-assistant/server/probe/ProbeService/Probe`){};function Xt(e){let t=/^pixso-debug(\d+)$/.exec(e);return t===null?null:Number(t[1])}function Zt(e){return e.filter(e=>Xt(e)!==null).sort((e,t)=>Xt(e)-Xt(t))}function Qt(e){let t=0;for(let n of e){let e=Xt(n);e!==null&&(t=Math.max(t,e))}return`pixso-debug${String(t+1)}`}function $t(e,t,n,r){return O.gen(function*(){let i=i=>e.exists(t.join(n,r,i)).pipe(O.orElseSucceed(()=>!1));return(yield*i(`local`))?!0:(yield*i(`remote`))?!1:yield*i(`tools.json`)})}function en(e,t,n,r){return e.readDirectory(n).pipe(O.orElseSucceed(()=>[]),O.flatMap(i=>{let a=Zt(i);return O.forEach(a,r=>$t(e,t,n,r).pipe(O.map(e=>[r,e]))).pipe(O.map(e=>e.filter(([,e])=>r===`local`?e:!e).map(([e])=>e)))}),O.flatMap(r=>O.forEach(r.slice(0,Math.max(0,r.length-10)),r=>e.remove(t.join(n,r),{recursive:!0,force:!0}).pipe(O.orElseSucceed(()=>void 0)),{discard:!0})),O.orElseSucceed(()=>void 0))}function tn(e,t,n,r){let i=String(e).split(t).join(n).split(r).join(`<root>`),a=/\bE[A-Z0-9]{2,15}\b(?=:)/.exec(i),o=a===null?`UNKNOWN`:a[0],s=/cause: (?:Error: )?(.+)$/.exec(i);return u(`dump write failed at {0} ({1}): {2}`,`запись дампа не удалась: {0} ({1}): {2}`,[n,o,(s===null?i.trim():s[1].trim()).replace(/[)\]]+$/,``).trim()])}const nn=/-32602|input validation|invalid arguments|invalid_type|missing required/i,rn=/requires|missing required|unsupported|not found|invalid/i,an=/^\s*(unsupported|missing required|error:)/i,on=/requires|missing required/i,sn=e=>e.startsWith(`enum`)?`string`:e.endsWith(`[]`)?`array`:e,cn=e=>{let t=/^enum\((.+)\)$/.exec(e);return t===null?null:t[1].split(`|`).sort()},ln=e=>e===null?`—`:e.join(`|`);function un(e,t=`local`){let n=[],r=new Map(e.map(e=>[e.name,e])),i=t===`remote`?m:g;for(let e of i){let t=r.get(e.name);if(t===void 0){n.push(u(`{0}: tool vanished from tools/list`,`{0}: инструмент исчез из tools/list`,[e.name]));continue}let i=new Map(t.params.map(e=>[e.name,e]));for(let t of e.params){let r=i.get(t.name);if(r===void 0){n.push(u(`{0}: param {1} vanished`,`{0}: параметр {1} исчез`,[e.name,t.name]));continue}sn(r.type)!==sn(t.type)&&n.push(u(`{0}: {1} — type {2} → {3}`,`{0}: {1} — тип {2} → {3}`,[e.name,t.name,t.type,r.type])),r.required!==t.required&&n.push(u(`{0}: {1} — required {2} → {3}`,`{0}: {1} — required {2} → {3}`,[e.name,t.name,String(t.required),String(r.required)]));let a=cn(t.type),o=r.enumValues===void 0?null:[...r.enumValues].sort();ln(a)!==ln(o)&&n.push(`${e.name}: ${t.name} — enum [${ln(a)}] → [${ln(o)}]`)}for(let r of t.params)e.params.some(e=>e.name===r.name)||n.push(u(`{0}: new param {1} ({2}) — not in contract`,`{0}: новый параметр {1} ({2}) — не в контракте`,[e.name,r.name,r.type]))}for(let t of e)i.some(e=>e.name===t.name)||n.push(u(`{0}: new tool — not in contract`,`{0}: новый инструмент — не в контракте`,[t.name]));return n}const dn=e=>`${(e/1024).toFixed(1)} ${l(`KB`,`КБ`)}`;function fn(e){try{return JSON.parse(e)}catch{return}}function pn(e,t,n,r){let i=n.length>0?u(`requires: {0}`,`требует: {0}`,[n.join(`, `)]):l(`args out of contract`,`аргументы вне контракта`);if(!r.ok){let n=!r.timedOut&&nn.test(r.message);return{tool:e.name,args:t,status:n?`needs-args`:`dead`,ms:r.ms,rawBytes:0,detail:r.timedOut?u(`timeout {0}s`,`таймаут {0}с`,[Math.round(r.ms/1e3)]):n?i:l(`error · see the report`,`ошибка · см. отчёт`),errorText:r.message,payload:null,blobs:[]}}let a=r.texts.join(`
|
|
107
|
+
`),{payload:o,blobs:s}=T(r.result),c=B.Buffer.byteLength(a,`utf8`);if(r.isError){let n=nn.test(a);return{tool:e.name,args:t,status:n?`needs-args`:`dead`,ms:r.ms,rawBytes:c,detail:n?i:l(`tool error · see the report`,`ошибка инструмента · см. отчёт`),errorText:a,payload:o,blobs:s}}let d=r.texts[0]??``,f=fn(d),p=typeof f==`object`&&f&&`message`in f&&typeof f.message==`string`?f.message:null;if(typeof f==`object`&&f&&`success`in f&&f.success===!1||p!==null&&rn.test(p)||an.test(d)){let n=on.test(p??d);return{tool:e.name,args:t,status:n?`needs-args`:`dead`,ms:r.ms,rawBytes:c,detail:n?i:l(`tool error · see the report`,`ошибка инструмента · см. отчёт`),errorText:a,payload:o,blobs:s}}return{tool:e.name,args:t,status:B.Buffer.byteLength(a.trim(),`utf8`)<=64?`empty`:`ok`,ms:r.ms,rawBytes:c,detail:`${r.ms} ${l(`ms`,`мс`)} · ${dn(c)}`,errorText:null,payload:o,blobs:s}}const mn=e=>({tool:e.tool,args:JSON.stringify(e.args),status:e.status,detail:e.detail});function hn(e){if(typeof e!=`object`||!e||!(`content`in e))return null;let t=e.content;if(!Array.isArray(t))return null;for(let e of t){if(typeof e!=`object`||!e)continue;let t=e;if(t.type===`text`){if(typeof t.text==`string`)return t.text;if(typeof t.text==`object`&&t.text!==null){let e=t.text;if(e.__encodedJson===!0)return JSON.stringify(e.value)}}}return null}function gn(e){return O.gen(function*(){let t=hn(e.dslPayload);if(t===null)return[];let n=de(t,e.requestedGuid);if(n===null)return[];let r=new Map;return yield*Me({root:n,concurrency:_,nodesFetchEnabled:e.nodesFetchEnabled,alreadyResolved:re,onProgress:()=>O.void,fetchNode:t=>O.gen(function*(){let n=ae(e.remoteTarget,t),i=yield*e.callToolRaw(`get_node_dsl`,n),{payload:a,blobs:o}=i.ok?T(i.result):{payload:null,blobs:[]},s=i.ok?i.texts.join(`
|
|
108
|
+
`):``,c=!i.ok||i.isError;return r.set(t,{tool:`get_node_dsl`,args:n,status:c?`dead`:`ok`,ms:i.ms,rawBytes:B.Buffer.byteLength(s,`utf8`),detail:c?l(`node fetch failed · see the record`,`узел не загрузился · см. запись`):`${String(i.ms)} ${l(`ms`,`мс`)}`,errorText:i.ok?i.isError?s:null:i.message,payload:a,blobs:o}),c?{ok:!1,message:i.ok?s:i.message}:{ok:!0,raw:i.texts[0]??``,ms:i.ms}})}),[...r.values()]})}const _n=O.gen(function*(){let t=yield*Ce,n=yield*Ae,r=yield*Gt,i=yield*Oe,a=yield*H.FileSystem,o=yield*A.Path,s=yield*U.make(1),c=yield*j.make(null),d=(e,n,r)=>O.gen(function*(){let{args:i,requiredNames:a}=E(e.name,e.inputSchema,n),o=pn(e,i,a,yield*t.callToolRaw(e.name,i));return yield*j.update(r,t=>new Map(t).set(e.name,o)),o}),f=()=>O.gen(function*(){let s=yield*t.listToolsRaw();if(!s.ok)return yield*new e({detail:`${l(`Probe failed: Pixso MCP is unreachable`,`Проба не удалась: Pixso MCP недоступен`)}: ${s.message}`});let c=yield*V.currentTimeMillis,f=new Date(c).toISOString(),p=Qt(yield*a.readDirectory(r.diagnosticsDir).pipe(O.orElseSucceed(()=>[]))),m=o.join(r.diagnosticsDir,p),h=un(s.tools),g=s.tools.filter(e=>x(e.name)),_=g.find(e=>e.name===`get_node_dsl`),v=g.filter(e=>e.name!==`get_node_dsl`),S=yield*j.make(new Map),C=yield*j.make({guid:null,pageGuid:null,reason:`probe deadline exceeded before target derivation`}),w=6*t.callTimeoutMs,T=yield*O.gen(function*(){let e=_===void 0?null:yield*d(_,null,S);yield*O.yieldNow;let t=e===null?{guid:null,pageGuid:null,reason:`get_node_dsl absent from tools/list`}:e.status===`ok`?y(e.payload):{guid:null,pageGuid:null,reason:`get_node_dsl ${e.status} — staying in selection mode`};return yield*j.set(C,t),yield*O.forEach(v,e=>d(e,t.guid,S),{concurrency:4}),!0}).pipe(O.timeoutOrElse({duration:w,orElse:()=>O.succeed(!1)})),ee=yield*j.get(S),D=yield*j.get(C),k=e=>({tool:e.name,args:E(e.name,e.inputSchema,e.name===`get_node_dsl`?null:D.guid).args,status:`dead`,ms:w,rawBytes:0,detail:u(`probe timeout {0}s`,`таймаут пробы {0}с`,[Math.round(w/1e3)]),errorText:`probe deadline exceeded`,payload:null,blobs:[]}),A=[..._===void 0?[]:[_],...v].map(e=>ee.get(e.name)??k(e)),te=T?h:[...h,u(`probe aborted by the overall timeout ({0}s)`,`проба прервана по общему таймауту ({0}с)`,[Math.round(w/1e3)])],M=o.relative(i.rootDir,m),N=A.find(e=>e.tool===`get_node_dsl`)?.payload,P=yield*gn({dslPayload:N,requestedGuid:D.guid,remoteTarget:null,nodesFetchEnabled:n.enabled,callToolRaw:(e,n)=>t.callToolRaw(e,n)}),F=yield*O.sync(()=>z({dumpDir:m,source:`local`,atIso:f,endpoint:t.endpoint,target:{guid:D.guid,fileKey:null,pageGuid:D.pageGuid},frameName:b(N,D.guid),tools:s.tools,records:A,nodeRecords:P})).pipe(O.as({ok:!0}),O.catchCause(e=>O.logError(`[pixso] probe report write failed`,{cause:String(e)}).pipe(O.as({ok:!1,deviation:tn(e,m,M,i.rootDir)})))),I=F.ok,ne=F.ok?te:[...te,F.deviation];yield*en(a,o,r.diagnosticsDir,`local`);let L={atIso:f,rows:A.map(mn),deviations:ne,savedTo:I?M:``};return yield*r.recordProbe(L),yield*O.logDebug(`[pixso] probe`,{tools:A.length,ok:A.filter(e=>e.status===`ok`).length,dead:A.filter(e=>e.status===`dead`).length,needsArgs:A.filter(e=>e.status===`needs-args`).length,deviations:ne.length,finishedInTime:T,savedTo:I?m:``}),L}).pipe(O.provideService(H.FileSystem,a),O.provideService(A.Path,o)),p=s.withPermits(1)(O.gen(function*(){let e=yield*j.get(c);if(e!==null)return{leads:!1,deferred:e};let t=yield*he.make();return yield*j.set(c,t),{leads:!0,deferred:t}}));return{run:()=>O.gen(function*(){let e=yield*p;return e.leads?yield*f().pipe(O.onExit(t=>j.set(c,null).pipe(O.andThen(he.done(e.deferred,t))))):yield*he.await(e.deferred)}),runRemote:(e,t)=>O.gen(function*(){let s=yield*t.listToolsRaw(),c=new Map(s.ok?s.tools.map(e=>[e.name,e.inputSchema]):[]),d=yield*V.currentTimeMillis,f=new Date(d).toISOString(),p=Qt(yield*a.readDirectory(r.diagnosticsDir).pipe(O.orElseSucceed(()=>[]))),m=o.join(r.diagnosticsDir,p),g=o.relative(i.rootDir,m),_=[...h],v=[],y=[];for(let n of _){let r=ee(n,c.get(n)??null,e).args,i=yield*t.callToolRaw(n,r),a=i.ok?i.texts.join(`
|
|
109
|
+
`):``,{payload:o,blobs:s}=i.ok?T(i.result):{payload:null,blobs:[]},u=i.ok&&i.isError,d=u&&nn.test(a);v.push({tool:n,args:JSON.stringify(r),status:i.ok?u?d?`needs-args`:`dead`:`ok`:`dead`,detail:i.ok?u?d?l(`needs different args · see the report`,`нужны другие аргументы · см. отчёт`):l(`tool error · see the report`,`ошибка инструмента · см. отчёт`):`${String(i.ms)} ${l(`ms`,`мс`)} · ${dn(B.Buffer.byteLength(a,`utf8`))}`:i.message}),y.push({tool:n,args:r,status:i.ok?u?d?`needs-args`:`dead`:`ok`:`dead`,ms:i.ms,rawBytes:B.Buffer.byteLength(a,`utf8`),detail:v.at(-1).detail,errorText:i.ok?u?a:null:i.message,payload:o,blobs:s})}let x=y.find(e=>e.tool===`get_node_dsl`)?.payload,S=yield*gn({dslPayload:x,requestedGuid:e.itemId,remoteTarget:e,nodesFetchEnabled:n.enabled,callToolRaw:(e,n)=>t.callToolRaw(e,n)}),C=yield*O.sync(()=>z({dumpDir:m,source:`remote`,atIso:f,endpoint:t.endpoint,target:{guid:e.itemId,fileKey:e.fileKey,pageGuid:null},frameName:b(x,e.itemId),tools:s.ok?s.tools:null,records:y,nodeRecords:S})).pipe(O.as({ok:!0}),O.catchCause(e=>O.logError(`[pixso] remote probe dump write failed`,{cause:String(e)}).pipe(O.as({ok:!1,deviation:tn(e,m,g,i.rootDir)})))),w=C.ok,E=C.ok?null:C.deviation;yield*en(a,o,r.diagnosticsDir,`remote`);let D=s.ok?null:u(`remote tools/list failed ({0}) — every tool call fell back to schema-less minimal args`,`remote tools/list не удался ({0}) — каждый вызов инструмента использовал минимальные аргументы без схемы`,[s.message]),k=s.ok?un(s.tools,`remote`):[];return{atIso:f,rows:v,deviations:[...D===null?[]:[D],...k,...E===null?[]:[E]],savedTo:w?g:``}}).pipe(O.provideService(H.FileSystem,a),O.provideService(A.Path,o))}}),vn=k.effect(Yt,_n),yn=new Set([`mcp-down`,`tool-timeout`,`dsl-error`,`parse-error`,`components-error`,`internal-error`,`access-denied`,`cancelled`]),bn=e=>yn.has(e),xn=(e,t)=>{let n=Date.parse(e),r=Date.parse(t);return Number.isNaN(n)||Number.isNaN(r)?null:r-n},Sn=(e,t)=>{let n=xn(e.startedAtIso,e.settledAtIso),r=t.toolTimings.reduce((e,t)=>e+t.ms,0);return{outcome:e.outcome,ms:n,mcpMs:r,localMs:n===null?null:n-r,failedStep:e.failedStep,cardId:e.cardId,nodeId:t.nodeId,nodes:t.nodesParsed,nodeIssues:t.nodesWithIssues,unknownKeys:t.unknownKeys.length,unknownEnums:t.unknownEnums.length,unresolvedLibraries:t.unresolvedLibraries.length,warnings:t.diagnostics.filter(e=>e.severity===`warning`).length,catalog:t.catalogStatus,duplicate:t.duplicate,detail:e.detail}},Cn=e=>({outcome:e.outcome,ms:e.toolTimings.reduce((e,t)=>e+t.ms,0),nodeId:e.nodeId,nodes:e.nodesParsed,unknownKeys:e.unknownKeys.length,unknownEnums:e.unknownEnums.length,byteIdentical:e.byteDiff===null?null:e.byteDiff.identical,byteNote:e.byteDiff===null?null:e.byteDiff.note}),wn={currentSeq:0,settledSeq:null},Tn=(e,t)=>t>0&&t===e.currentSeq&&e.settledSeq!==t,En=e=>j.modify(e,e=>{let t=e.currentSeq+1;return[t,{currentSeq:t,settledSeq:null}]}),Dn=(e,t)=>j.modify(e,e=>Tn(e,t)?[!0,{...e,settledSeq:t}]:[!1,e]),On=(e,t)=>j.get(e).pipe(O.map(e=>e.currentSeq===t)),kn=be.seconds(180),An=2e3,jn=be.seconds(10);function Mn(e){return{file_key:e.fileKey,guid:e.itemId}}function Nn(e,t){try{return`${new URL(e).origin}/app/design/${t.fileKey}?item-id=${t.itemId}`}catch{return null}}var Pn=class extends D.Service()(`@smart-tools/t3-code-pixso-mcp-assistant/server/scan/ScanJobService/ScanJob`){};function Fn(e){if(typeof e!=`object`||!e||!(`content`in e))return null;let t=e.content;if(!Array.isArray(t))return null;for(let e of t){if(typeof e!=`object`||!e)continue;let t=e;if(!(t.type!==`image`||typeof t.data!=`string`||t.data===``)&&!(typeof t.mimeType==`string`&&t.mimeType!==`image/png`))return t.data}return null}const In=O.gen(function*(){let t=yield*Ce,n=yield*Ae,r=e=>{let n=(e,t)=>({base64:null,timing:{tool:`get_image`,ms:t,ok:!1,detail:e}});return t.callToolRaw(`get_image`,{itemId:e}).pipe(O.map(e=>e.ok?e.isError?n(`get_image returned a tool error`,e.ms):{base64:Fn(e.result),timing:{tool:`get_image`,ms:e.ms,ok:!0,detail:null}}:n(e.message,e.ms)),O.timeoutOrElse({duration:jn,orElse:()=>O.succeed(n(`get_image timed out`,be.toMillis(jn)))}),O.catchCause(e=>O.succeed(n(String(e),0))))},i=yield*Gt,a=O.map(V.currentTimeMillis,e=>new Date(e).toISOString()),o=o=>O.gen(function*(){let{origin:s}=o,c=yield*K.make({phase:`idle`,origin:s}),d=yield*U.make(1),f=yield*j.make(null),p=yield*j.make(wn),m=(e,t)=>{let n=Sn(e,t);return bn(e.outcome)?O.logError(`[pixso] scan failed`,n):O.logDebug(`[pixso] scan settled`,n)},h=(e,t)=>On(p,e).pipe(O.flatMap(e=>e?K.set(c,t):O.void)),g=e=>O.uninterruptible(O.gen(function*(){if(!(yield*Dn(p,e.seq))){yield*O.logDebug(`[pixso] scan settle dropped — run already settled or superseded`,{seq:e.seq,outcome:e.outcome});return}e.cardId===null&&(yield*i.recordReport({atIso:e.settledAtIso,data:e.report,origin:e.origin}).pipe(O.orElseSucceed(()=>void 0)));let t={phase:`settled`,outcome:e.outcome,failedStep:e.failedStep,cardId:e.cardId,detail:e.detail,...e.httpStatus===void 0?{}:{httpStatus:e.httpStatus},startedAtIso:e.startedAtIso,settledAtIso:e.settledAtIso,origin:e.origin,...e.enriched!==void 0&&e.enriched.length>0?{enriched:e.enriched}:{},...e.resolvedNodes!==void 0&&(e.resolvedNodes.fetched.length>0||e.resolvedNodes.failed.length>0)?{resolvedNodes:e.resolvedNodes}:{}};yield*K.set(c,t),yield*m(t,e.report)})),v=(e,t,n,r,i,o,s,c=null,l)=>a.pipe(O.flatMap(a=>g({seq:e,startedAtIso:t,settledAtIso:a,outcome:n,failedStep:r,cardId:i,origin:o,report:s,detail:c,...l===void 0?{}:{httpStatus:l}}))),y=(e,t,n,r,i)=>O.gen(function*(){let{stage:a,reason:o}=r,s=yield*j.get(n);switch(o.kind){case`multi-text`:yield*O.logError(`[pixso] get_node_dsl returned multiple text items`,{items:o.items,sizes:o.sizes}),yield*v(e,t,`dsl-error`,1,null,i,P({...L,outcome:`dsl-error`,failedStep:1,toolTimings:s}),`get_node_dsl: ${String(o.items)} ${l(`text items in the response — expected 1`,`текстовых частей в ответе — ожидалась 1`)}`);return;case`over-byte-cap`:yield*v(e,t,`dsl-error`,1,null,i,P({...L,outcome:`dsl-error`,failedStep:1,toolTimings:s}),l(`The selection is too large to read — pick a smaller frame.`,`Выделение слишком велико для чтения — выберите фрейм поменьше.`));return;case`parse-failed`:{let n=a.parsed===null?null:oe(a.parsed,o.outcome);yield*v(e,t,o.outcome,o.failedStep,null,i,P({...L,outcome:o.outcome,failedStep:o.failedStep,parsed:a.parsed,root:a.root,toolTimings:s}),n);return}case`requested-root-absent`:yield*v(e,t,`empty-selection`,3,null,i,P({...L,outcome:`empty-selection`,failedStep:3,parsed:a.parsed,root:a.root,toolTimings:s}),u(`Requested node {0} is not present in the response ({1} root(s) returned)`,`Запрошенный узел {0} отсутствует в ответе ({1} корневых узлов получено)`,[o.requestedGuid,o.availableGuids.length]));return;case`incompatible-version`:yield*O.logError(`[pixso] unsupported DSL version rejected`,{detail:o.detail}),yield*v(e,t,`parse-error`,3,null,i,P({...L,outcome:`parse-error`,failedStep:3,parsed:a.parsed,root:a.root,toolTimings:s}),pe());return;case`tree-too-deep`:yield*v(e,t,`internal-error`,3,null,i,P({outcome:`internal-error`,failedStep:3,parsed:a.parsed,root:a.root,componentsUsed:[],catalogStatus:`ok`,catalogDiagnostics:a.catalogDump?.diagnostics??[],toolTimings:s,duplicate:!1,byteDiff:null}),o.message);return}}),b=(e,o,c)=>O.gen(function*(){let d=yield*j.make([]),f=yield*j.make(1),p=e=>j.update(d,t=>[...t,e]),m=c?.mcp??t,b=c===void 0?{}:Mn(c.target),x=null,S=t=>({phase:`running`,step:t,startedAtIso:e,origin:s,...x===null?{}:{nodes:x}});return yield*O.gen(function*(){let t=yield*m.callTool(`get_node_dsl`,b);if(!t.ok){yield*p({tool:`get_node_dsl`,ms:t.ms,ok:!1,detail:t.message});let{outcome:n,failedStep:r}=F(t),i=yield*j.get(d);yield*v(o,e,n,r,null,s,P({...L,outcome:n,failedStep:r,toolTimings:i}),`get_node_dsl: ${t.message}`,t.httpStatus);return}let C=ce(t.texts,c?.target.itemId??null);if(!C.ok&&C.reason.kind===`multi-text`){yield*y(o,e,d,C,s);return}if(yield*p({tool:`get_node_dsl`,ms:t.ms,ok:!0,detail:null}),!C.ok){yield*y(o,e,d,C,s);return}let{root:w,compat:T,dslRaw:E}=C,ee=yield*i.getResolvedNodes(Qe(E)).pipe(O.orElseSucceed(()=>null)),D=yield*V.currentTimeMillis,k=yield*Me({root:w,concurrency:_,nodesFetchEnabled:n.enabled,alreadyResolved:ee??re,fetchNode:e=>m.callTool(`get_node_dsl`,ae(c?.target??null,e)).pipe(O.map(e=>e.ok?{ok:!0,raw:e.texts[0]??``,ms:e.ms}:{ok:!1,message:e.message})),onProgress:(e,t)=>O.gen(function*(){t!==0&&(x={done:e,total:t},yield*h(o,S(1)))})}),A=(yield*V.currentTimeMillis)-D,M=k.envelope,N=ue(M),I=N.fetched.length>0||N.failed.length>0,ne=Object.values(M.nodes).map(e=>({guid:e.guid,raw:e.raw})),R=ne.length===0?C:ce(t.texts,c?.target.itemId??null,ne),ie=R.ok?R:C;R.ok||(yield*O.logError(`[pixso] resolved-nodes re-parse failed gates — falling back to the root fetch`,{reason:R.reason.kind}));let oe=ie.parsed,le=ie.root;k.attempted>0&&(yield*p({tool:`get_node_dsl (nodes)`,ms:A,ok:N.failed.length===0,detail:N.failed.length===0?null:u(`{0} of {1} node fetches failed`,`не загрузилось узлов: {0} из {1}`,[N.failed.length,k.attempted])}));let de,fe,pe;if(c!==void 0)de={kind:`absent-by-design`},fe={base64:null},pe=null;else{yield*j.set(f,2),yield*h(o,S(2));let[e,t]=yield*O.all([m.callTool(`get_all_components`,{}),r(w.guid)],{concurrency:`unbounded`});e.ok&&e.texts.length>1&&(yield*O.logDebug(`[pixso] get_all_components extra text items`,{items:e.texts.length,extraSizes:e.texts.slice(1).map(e=>e.length)})),pe=e.ok?e.texts[0]??``:null,yield*p({tool:`get_all_components`,ms:e.ms,ok:e.ok,detail:e.ok?null:e.message}),yield*p(t.timing),de=e.ok?{kind:`fetched`,raw:pe??``}:{kind:`unavailable`},fe=t}yield*j.set(f,3),yield*h(o,S(3));let z=se(ie,de);if(!z.ok){yield*y(o,e,d,z,s);return}let{assembled:B,versionUnverified:he,card:H}=z,U=N.failed.length>0&&z.outcome===`success`?`success-warnings`:z.outcome,W=yield*j.get(d),ge=z.catalogDegraded?`failed`:`ok`,_e=P({outcome:U,failedStep:null,parsed:oe,root:le,componentsUsed:B.card.componentsUsed,catalogStatus:ge,catalogDiagnostics:z.stage.catalogDump?.diagnostics??[],toolTimings:W,duplicate:!1,byteDiff:null}),ve=[...he?[{severity:`warning`,code:`version-unverified`,message:`${l(`Format version outside the supported list — accepted by the structural compatibility check`,`Версия формата вне поддерживаемого списка — принята проверкой структурной совместимости`)} (${T.detail??``})`}]:[],...z.catalogDegraded?[{severity:`warning`,code:`catalog-degraded`,message:l(`The component catalog was not joined for this scan — component names and library links are unavailable`,`Каталог компонентов не был подключён для этого скана — имена компонентов и связи с библиотеками недоступны`)}]:[],...N.failed.length>0?[{severity:`warning`,code:`nodes-degraded`,message:u(`{0} additional node(s) could not be fetched — nested component overrides may be incomplete`,`Не удалось загрузить дополнительных узлов: {0} — переопределения вложенных компонентов могут быть неполными`,[N.failed.length])}]:[],...k.truncated?[{severity:`warning`,code:`nodes-truncated`,message:u(`Nested-node discovery stopped at the {0}-node safety cap`,`Обход вложенных узлов остановлен на защитном пределе {0}`,[te])}]:[],..._e.diagnostics],G=ve.length>0?{..._e,diagnostics:ve}:_e,ye=yield*a;yield*i.persistScan({dslRaw:E,catalogRaw:z.catalogDegraded?null:pe,imagePngBase64:fe.base64,capturedAtIso:ye,card:{...H,source:s},summary:B.summary,report:G,origin:s,provenance:{source:s,fileKey:c?.target.fileKey??null,designUrl:c===void 0?null:Nn(m.endpoint,c.target)},...I?{resolvedNodes:M}:{}},t=>g({seq:o,startedAtIso:e,settledAtIso:ye,outcome:t.duplicate?`reimport`:U,failedStep:null,cardId:t.id,detail:t.duplicate||U!==`success-warnings`?null:me(G),report:{...G,duplicate:t.duplicate,enriched:t.enriched},origin:s,enriched:t.enriched,...I?{resolvedNodes:N}:{}}))}).pipe(O.timeoutOrElse({duration:kn,orElse:()=>O.gen(function*(){let t=yield*j.get(d),n=yield*j.get(f);yield*v(o,e,`tool-timeout`,n,null,s,P({...L,outcome:`tool-timeout`,failedStep:n,toolTimings:t}))})}),O.catchCause(t=>O.gen(function*(){let n=String(t);yield*O.logError(`[pixso] scan pipeline defect`,{cause:n});let r=yield*j.get(d),i=yield*j.get(f),a=n.length>An?`${n.slice(0,An)}…`:n;yield*v(o,e,`dsl-error`,i,null,s,P({...L,outcome:`dsl-error`,failedStep:i,toolTimings:[...r,{tool:`pipeline`,ms:0,ok:!1,detail:a}]}))})))});return{stateRef:c,start:t=>d.withPermits(1)(O.gen(function*(){if(t!==void 0&&(t.target.fileKey.trim()===``||t.target.itemId.trim()===``))return yield*new e({detail:l(`No design selected — paste a Pixso frame link first.`,`Макет не выбран — сначала вставьте ссылку на фрейм Pixso.`)});let n=yield*K.get(c);if(n.phase===`running`)return n;let r=yield*a,i={phase:`running`,step:0,startedAtIso:r,origin:s},o=yield*En(p);yield*K.set(c,i),yield*O.logDebug(`[pixso] scan start`,{startedAtIso:r,seq:o,origin:s});let u=yield*O.forkDetach(b(r,o,t));return yield*j.set(f,u),i})),cancel:d.withPermits(1)(O.gen(function*(){let e=yield*K.get(c);if(e.phase!==`running`)return e;yield*En(p);let t=yield*j.get(f);t!==null&&(yield*xe.interrupt(t)),yield*j.set(f,null);let n={phase:`idle`,origin:s};return yield*K.set(c,n),yield*O.logDebug(`[pixso] scan cancelled`,{origin:s}),n}))}}),s=yield*o(Rn.local),c=yield*o(Rn.remote),d=e=>e===void 0?s.start():c.start(e),f=e=>e===`remote`?c.cancel:s.cancel,p=()=>O.gen(function*(){if((yield*K.get(s.stateRef)).phase===`running`)return yield*new e({detail:l(`A scan is already running — wait for it to finish.`,`Скан уже выполняется — дождитесь его завершения.`)});let n=yield*t.listTools();if(!n.ok)return yield*O.logError(`[pixso] check failed`,{ms:n.ms,timedOut:n.timedOut,origin:n.origin,message:n.message}),yield*new e({detail:`${l(`Failed to connect to Pixso MCP`,`Не удалось подключиться к Pixso MCP`)}: ${n.message}`});let r={atIso:yield*a,tools:n.tools.map(e=>({name:e.name,description:e.description,write:S(e.name),params:e.params.map(e=>({name:e.name,type:e.type,required:e.required,...e.description===void 0?{}:{description:e.description}}))}))};return yield*i.recordCheck(r),yield*O.logDebug(`[pixso] check ok`,{ms:n.ms,tools:r.tools.length,write:r.tools.filter(e=>e.write).length}),r}),m=()=>O.gen(function*(){if((yield*K.get(s.stateRef)).phase===`running`)return yield*new e({detail:l(`A scan is already running — wait for it to finish.`,`Скан уже выполняется — дождитесь его завершения.`)});let n=[],r=yield*t.callTool(`get_node_dsl`,{}),o=yield*a;if(!r.ok){n.push({tool:`get_node_dsl`,ms:r.ms,ok:!1,detail:r.message});let{outcome:e,failedStep:t}=F(r),a={atIso:o,origin:`local`,data:P({...L,outcome:e,failedStep:t,toolTimings:n})};return yield*i.recordReport(a),a}let c=r.texts[0]??``;n.push({tool:`get_node_dsl`,ms:r.ms,ok:!0,detail:null});let u=ce(r.texts,null),d=u.ok?u.parsed:u.stage.parsed,f=d!==null&&d.detachedNodes.length===0?d.root:null,p=null;if(f!==null){let e=yield*i.findScanByNodeId(f.guid);if(e!==null){let t=yield*i.getCardRaw(e).pipe(O.orElseSucceed(()=>null));t!==null&&(p=N(t,c))}}if(!u.ok){let{stage:e,reason:t}=u,r={atIso:o,origin:`local`,data:(()=>{switch(t.kind){case`multi-text`:case`over-byte-cap`:return P({...L,outcome:`dsl-error`,failedStep:1,toolTimings:n,byteDiff:p});case`parse-failed`:return P({...L,outcome:t.outcome,failedStep:t.failedStep,parsed:e.parsed,root:e.root,toolTimings:n,byteDiff:p});case`incompatible-version`:return P({...L,outcome:`parse-error`,failedStep:3,parsed:e.parsed,root:e.root,toolTimings:n,byteDiff:p});case`requested-root-absent`:return P({...L,outcome:`empty-selection`,failedStep:3,parsed:e.parsed,root:e.root,toolTimings:n,byteDiff:p});case`tree-too-deep`:return P({...L,outcome:`internal-error`,failedStep:3,toolTimings:n,byteDiff:p})}})()};return yield*i.recordReport(r),r}let{parsed:m,root:h}=u,g={atIso:o,origin:`local`,data:P({outcome:m.diagnostics.some(e=>e.severity===`warning`)?`success-warnings`:`success`,failedStep:null,parsed:m,root:h,componentsUsed:[],catalogStatus:`skipped`,catalogDiagnostics:[],toolTimings:n,duplicate:!1,byteDiff:p})};return yield*i.recordReport(g),g}),h=()=>m().pipe(O.tap(e=>O.logDebug(`[pixso] rescan`,Cn(e.data)))),g=(t,n)=>O.gen(function*(){if((yield*K.get(c.stateRef)).phase===`running`)return yield*new e({detail:l(`A scan is already running — wait for it to finish.`,`Скан уже выполняется — дождитесь его завершения.`)});let r=[],o=Mn(t),s=yield*n.callTool(`get_node_dsl`,o),u=yield*a;if(!s.ok){r.push({tool:`get_node_dsl`,ms:s.ms,ok:!1,detail:s.message});let{outcome:e,failedStep:t}=F(s),n={atIso:u,origin:`remote`,data:P({...L,outcome:e,failedStep:t,toolTimings:r})};return yield*i.recordReport(n),n}let d=s.texts[0]??``;r.push({tool:`get_node_dsl`,ms:s.ms,ok:!0,detail:null});let f=ce([d],t.itemId);if(!f.ok){let{stage:e,reason:t}=f,n={atIso:u,origin:`remote`,data:(()=>{switch(t.kind){case`multi-text`:case`over-byte-cap`:return P({...L,outcome:`dsl-error`,failedStep:1,toolTimings:r});case`parse-failed`:return P({...L,outcome:t.outcome,failedStep:t.failedStep,parsed:e.parsed,root:e.root,toolTimings:r});case`incompatible-version`:return P({...L,outcome:`parse-error`,failedStep:3,parsed:e.parsed,root:e.root,toolTimings:r});case`requested-root-absent`:return P({...L,outcome:`empty-selection`,failedStep:3,parsed:e.parsed,root:e.root,toolTimings:r});case`tree-too-deep`:return P({...L,outcome:`internal-error`,failedStep:3,toolTimings:r})}})()};return yield*i.recordReport(n),n}let{parsed:p,root:m}=f,h={atIso:u,origin:`remote`,data:P({outcome:p.diagnostics.some(e=>e.severity===`warning`)?`success-warnings`:`success`,failedStep:null,parsed:p,root:m,componentsUsed:[],catalogStatus:`skipped`,catalogDiagnostics:[],toolTimings:r,duplicate:!1,byteDiff:null})};return yield*i.recordReport(h),h});return{state:K.get(s.stateRef),changes:Se.merge(K.changes(s.stateRef),K.changes(c.stateRef)),start:d,cancel:f,check:p,rescanDebug:h,remoteScanProbe:(e,t)=>g(e,t).pipe(O.tap(e=>O.logDebug(`[pixso] remote scan probe`,Cn(e.data)))),reparseStored:()=>O.gen(function*(){let t=yield*K.get(s.stateRef),n=yield*K.get(c.stateRef);if(t.phase===`running`||n.phase===`running`)return yield*new e({detail:l(`A scan is already running — wait for it to finish.`,`Скан уже выполняется — дождитесь его завершения.`)});let r=yield*i.reparseScans(({dslRaw:e,catalogRaw:t,rootGuid:n,resolvedNodes:r})=>{let i=ce([e],n,r===null?void 0:Object.values(r.nodes));if(!i.ok)return null;let{parsed:a,root:o,compat:s}=i,c=t===null?null:w(t),l=c!==null&&R(c)?c.entries:[];if(ne(o)!==null)return null;let u=M(a,o,l);return{card:s.verdict===`compatible`?{...u.card,versionUnverified:!0}:u.card,summary:u.summary}});return yield*O.logDebug(`[pixso] reparse`,{...r}),r})}}),Ln=k.effect(Pn,In),Rn={local:{origin:`local`,transport:Ce.key,addressing:`selection`,auth:`none`},remote:{origin:`remote`,transport:Ee.key,addressing:`fileKey+itemId`,auth:`gear-token`}};Object.values(Rn);var zn=class extends D.Service()(`@smart-tools/t3-code-pixso-mcp-assistant/server/PixsoAssistantService/PixsoAssistant`){};const Bn=O.gen(function*(){let t=yield*Gt,n=yield*Pn,r=yield*Yt,i=yield*Oe,a=yield*A.Path;yield*O.sync(()=>I([a.join(i.rootDir,`fonts`)]));let o=yield*Ee,s=yield*j.make(new Map);return{getSnapshot:()=>t.getSnapshot(),getCard:e=>t.getCard(e),getCardRaw:e=>t.getCardRaw(e).pipe(O.map(e=>({raw:e}))),getCardImage:e=>t.getCardImage(e).pipe(O.map(e=>({pngBase64:e}))),removeCard:e=>t.removeCard(e),mutateGallery:e=>t.mutateGallery(e),getLatestReport:()=>t.getLatestReport(),getCatalog:e=>O.gen(function*(){let n=(yield*j.get(s)).get(e);if(n!==void 0)return n;let{raw:r,capturedAtIso:i}=yield*t.getCatalogRaw(e),a=v(i,w(r).entries);return yield*j.update(s,t=>{let n=new Map(t);if(n.size>=2&&!n.has(e)){let e=n.keys().next().value;e!==void 0&&n.delete(e)}return n.set(e,a),n}),a}),scanStart:r=>r===void 0?n.start():O.gen(function*(){let i=yield*t.getRemoteToken();if(i===null)return yield*new e({detail:l(`No remote token saved — set one in settings first.`,`Токен для удалённого доступа не задан — сначала задайте его в настройках.`)});let a=o.makeClient({Token:i});return yield*n.start({target:r,mcp:a})}),scanCancel:e=>n.cancel(e??`local`),scanStates:()=>n.changes,check:()=>n.check(),probe:()=>r.run(),rescanDebug:()=>n.rescanDebug(),reparseStored:()=>n.reparseStored(),remoteTokenCheck:n=>O.gen(function*(){let r=n??(yield*t.getRemoteToken());if(r===null||r.trim()===``)return yield*new e({detail:l(`No token to check — enter one first.`,`Нечего проверять — сначала введите токен.`)});let i=yield*o.makeClient({Token:r}).listTools();return i.ok?{toolCount:i.tools.length,latencyMs:i.ms}:yield*new e({detail:`${l(`Could not verify the token`,`Не удалось проверить токен`)}: ${i.message}`,httpStatus:i.httpStatus})}),remoteTokenSave:e=>t.setRemoteToken(e).pipe(O.map(()=>({tokenSet:!0}))),remoteTokenDelete:()=>t.clearRemoteToken(),remoteModeSet:e=>t.setRemoteByDefault(e),remoteToolsList:()=>O.gen(function*(){let n=yield*t.getRemoteToken();if(n===null||n.trim()===``)return yield*new e({detail:l(`No token to check — enter one first.`,`Нечего проверять — сначала введите токен.`)});let r=yield*o.makeClient({Token:n}).listTools();return r.ok?{tools:r.tools.map(e=>({name:e.name,description:e.description,write:S(e.name),params:e.params.map(e=>({name:e.name,type:e.type,required:e.required,...e.description===void 0?{}:{description:e.description}}))}))}:yield*new e({detail:`${l(`Could not list remote tools`,`Не удалось получить список инструментов`)}: ${r.message}`,httpStatus:r.httpStatus})}),remoteScanProbe:r=>O.gen(function*(){let i=yield*t.getRemoteToken();if(i===null||i.trim()===``)return yield*new e({detail:l(`No token to check — enter one first.`,`Нечего проверять — сначала введите токен.`)});let a=o.makeClient({Token:i});return yield*n.remoteScanProbe(r,a)}),remoteFullProbe:n=>O.gen(function*(){let i=yield*t.getRemoteToken();if(i===null||i.trim()===``)return yield*new e({detail:l(`No token to check — enter one first.`,`Нечего проверять — сначала введите токен.`)});let a=o.makeClient({Token:i});return yield*r.runRemote(n,a)})}}),Vn=k.effect(zn,Bn).pipe(k.provide(Ln),k.provide(vn),k.provide(Jt)),Hn=Vn.pipe(k.provide(De),k.provide(je)),Un=Vn.pipe(k.provide(je)),Wn=e=>Vn.pipe(k.provide(De),k.provide(k.succeed(Ae,{enabled:e})));export{Ce as C,we as E,Oe as S,Ee as T,kt as _,Pn as a,Ae as b,Tn as c,Gt as d,Jt as f,gt as g,_t as h,Un as i,Yt as l,vt as m,Hn as n,Ln as o,yt as p,Wn as r,wn as s,zn as t,vn as u,bt as v,Te as w,je as x,Ne as y};
|