@yadsh/dsh-sleev 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/client.js +36 -24
- package/lib/index.js +40 -11
- package/lib/types/host/telemetry-store.d.ts +2 -2
- package/lib/types/index.d.ts +1 -0
- package/package.json +46 -46
package/lib/client.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
window.__ModuleLoader__.load({
|
|
2
|
-
id: "dsh-sleev",
|
|
2
|
+
id: "@yadsh/dsh-sleev",
|
|
3
3
|
factory: (require) => {
|
|
4
4
|
var module = { exports: {} };
|
|
5
5
|
var exports = module.exports;
|
|
@@ -240,17 +240,19 @@ window.__ModuleLoader__.load({
|
|
|
240
240
|
saving: "保存中…"
|
|
241
241
|
};
|
|
242
242
|
const CARD_STYLES = `
|
|
243
|
-
.dsh-
|
|
244
|
-
.dsh-
|
|
245
|
-
.dsh-
|
|
246
|
-
.dsh-
|
|
247
|
-
.dsh-
|
|
248
|
-
.dsh-
|
|
249
|
-
.dsh-
|
|
250
|
-
.dsh-
|
|
251
|
-
.dsh-
|
|
252
|
-
.dsh-
|
|
253
|
-
.dsh-
|
|
243
|
+
.dsh-plugin-card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;list-style:none;transition:border-color .16s,background .16s}
|
|
244
|
+
.dsh-plugin-card:hover{border-color:var(--dsw-alias-label-dimmed)}
|
|
245
|
+
.dsh-plugin-card--open{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}
|
|
246
|
+
.dsh-plugin-card__header{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}
|
|
247
|
+
.dsh-plugin-card__header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}
|
|
248
|
+
.dsh-plugin-card__head-text{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}
|
|
249
|
+
.dsh-plugin-card__name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}
|
|
250
|
+
.dsh-plugin-card__description{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}
|
|
251
|
+
.dsh-plugin-card__badge{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}
|
|
252
|
+
.dsh-plugin-card__chevron{width:14px;height:14px;color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}
|
|
253
|
+
.dsh-plugin-card--open .dsh-plugin-card__chevron{transform:rotate(180deg)}
|
|
254
|
+
.dsh-plugin-card__body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}
|
|
255
|
+
.dsh-sleev-button:focus-visible,.dsh-sleev-reset:focus-visible,.dsh-sleev-input:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}
|
|
254
256
|
.dsh-sleev-read-only{margin:12px 0 0;font-size:12px;line-height:1.5;color:var(--dsw-alias-label-tertiary)}
|
|
255
257
|
.dsh-sleev-pill{border-radius:999px;padding:1px 8px;font-size:11px;line-height:17px;font-weight:500;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);white-space:nowrap}
|
|
256
258
|
.dsh-sleev-field{display:flex;flex-direction:column;gap:6px;padding:12px 0}
|
|
@@ -274,6 +276,20 @@ textarea.dsh-sleev-input{height:64px;min-height:48px;padding:8px 12px;resize:ver
|
|
|
274
276
|
.dsh-sleev-save{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}
|
|
275
277
|
.dsh-sleev-button:disabled{opacity:.4;cursor:default}
|
|
276
278
|
`;
|
|
279
|
+
function ChevronDown() {
|
|
280
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
281
|
+
className: "dsh-plugin-card__chevron",
|
|
282
|
+
viewBox: "0 0 14 14",
|
|
283
|
+
fill: "none",
|
|
284
|
+
"aria-hidden": "true",
|
|
285
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
286
|
+
d: "m3.5 5.25 3.5 3.5 3.5-3.5",
|
|
287
|
+
stroke: "currentColor",
|
|
288
|
+
strokeLinecap: "round",
|
|
289
|
+
strokeLinejoin: "round"
|
|
290
|
+
})
|
|
291
|
+
});
|
|
292
|
+
}
|
|
277
293
|
function SettingsField(props) {
|
|
278
294
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
279
295
|
className: "dsh-sleev-field",
|
|
@@ -325,36 +341,32 @@ textarea.dsh-sleev-input{height:64px;min-height:48px;padding:8px 12px;resize:ver
|
|
|
325
341
|
onReset: () => props.resetField(field)
|
|
326
342
|
});
|
|
327
343
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
328
|
-
className: `dsh-
|
|
344
|
+
className: `dsh-plugin-card${open ? " dsh-plugin-card--open" : ""}`,
|
|
329
345
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
330
346
|
type: "button",
|
|
331
|
-
className: "dsh-
|
|
347
|
+
className: "dsh-plugin-card__header",
|
|
332
348
|
"aria-expanded": open,
|
|
333
349
|
"aria-label": `${props.t(open ? "collapse" : "expand")}: Sleev`,
|
|
334
350
|
onClick: () => setOpen(!open),
|
|
335
351
|
children: [
|
|
336
352
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
337
|
-
className: "dsh-
|
|
353
|
+
className: "dsh-plugin-card__head-text",
|
|
338
354
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
339
|
-
className: "dsh-
|
|
355
|
+
className: "dsh-plugin-card__name",
|
|
340
356
|
children: props.t("title")
|
|
341
357
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
342
|
-
className: "dsh-
|
|
358
|
+
className: "dsh-plugin-card__description",
|
|
343
359
|
children: props.t("description")
|
|
344
360
|
})]
|
|
345
361
|
}),
|
|
346
362
|
state.dirty ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
347
|
-
className: "dsh-
|
|
363
|
+
className: "dsh-plugin-card__badge",
|
|
348
364
|
children: props.t("unsaved")
|
|
349
365
|
}) : null,
|
|
350
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
351
|
-
className: "dsh-sleev-chevron",
|
|
352
|
-
"aria-hidden": "true",
|
|
353
|
-
children: "⌄"
|
|
354
|
-
})
|
|
366
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChevronDown, {})
|
|
355
367
|
]
|
|
356
368
|
}), open ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
357
|
-
className: "dsh-
|
|
369
|
+
className: "dsh-plugin-card__body",
|
|
358
370
|
children: [
|
|
359
371
|
!state.writable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
360
372
|
className: "dsh-sleev-read-only",
|
package/lib/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Service } from "@deepseek-ai/cordis";
|
|
2
2
|
import { installSettingsSection, settingsNamespace } from "@deepseek-ai/dsh-settings";
|
|
3
|
+
import { createHostLoggerSink, getPluginLogger } from "@yadsh/dsh-plugin-log";
|
|
3
4
|
import z from "@deepseek-ai/schemastery";
|
|
4
5
|
import { isAgentLoopRequest } from "@deepseek-ai/dsh-llm";
|
|
5
6
|
import { randomUUID } from "node:crypto";
|
|
@@ -141,13 +142,12 @@ var CallTelemetryStore = class {
|
|
|
141
142
|
const startedAt = this.now();
|
|
142
143
|
let usage;
|
|
143
144
|
let finished = false;
|
|
144
|
-
if (startConfig.logLevel === "debug") this.logger.debug(
|
|
145
|
+
if (startConfig.logLevel === "debug") this.logger.debug("sleev.call.start", {
|
|
145
146
|
callId,
|
|
146
147
|
provider: options.provider,
|
|
147
148
|
model: options.model,
|
|
148
|
-
kind
|
|
149
|
-
|
|
150
|
-
})}`);
|
|
149
|
+
kind
|
|
150
|
+
});
|
|
151
151
|
return {
|
|
152
152
|
observeUsage: (value) => {
|
|
153
153
|
usage = normalizeUsage(value);
|
|
@@ -176,9 +176,20 @@ var CallTelemetryStore = class {
|
|
|
176
176
|
this.completed.push(telemetry);
|
|
177
177
|
const finishConfig = this.reconfigure();
|
|
178
178
|
if (finishConfig.logLevel !== "off") {
|
|
179
|
-
const
|
|
180
|
-
|
|
181
|
-
|
|
179
|
+
const fields = {
|
|
180
|
+
callId: telemetry.callId,
|
|
181
|
+
provider: telemetry.provider,
|
|
182
|
+
model: telemetry.model,
|
|
183
|
+
kind: telemetry.kind,
|
|
184
|
+
durationMs: telemetry.durationMs,
|
|
185
|
+
...telemetry.providerUsage === void 0 ? {} : {
|
|
186
|
+
providerUsage: telemetry.providerUsage,
|
|
187
|
+
derived: telemetry.derived
|
|
188
|
+
},
|
|
189
|
+
result: telemetry.result
|
|
190
|
+
};
|
|
191
|
+
if (finishConfig.logLevel === "debug") this.logger.debug("sleev.call.end", fields);
|
|
192
|
+
else this.logger.info("sleev.call.end", fields);
|
|
182
193
|
}
|
|
183
194
|
}
|
|
184
195
|
};
|
|
@@ -197,6 +208,9 @@ var CallTelemetryStore = class {
|
|
|
197
208
|
//#endregion
|
|
198
209
|
//#region src/index.ts
|
|
199
210
|
const name = "dsh-sleev";
|
|
211
|
+
function pluginLogLevel(level) {
|
|
212
|
+
return level === "off" ? "silent" : level;
|
|
213
|
+
}
|
|
200
214
|
/** User-editable settings section rendered by the browser client card. */
|
|
201
215
|
const SLEEV_SETTINGS_NAMESPACE = settingsNamespace(SLEEV_SETTINGS_NAMESPACE_ID);
|
|
202
216
|
/** Host-side observer service. Routing itself remains owned by llm-pi-ai. */
|
|
@@ -204,6 +218,7 @@ var SleevIntegrationService = class extends Service {
|
|
|
204
218
|
static inject = ["llm"];
|
|
205
219
|
static Config = ConfigSchema;
|
|
206
220
|
telemetry;
|
|
221
|
+
logger;
|
|
207
222
|
constructor(ctx, input = {}) {
|
|
208
223
|
super(ctx, "sleev");
|
|
209
224
|
const resolvedEntry = resolveConfig(input);
|
|
@@ -214,12 +229,26 @@ var SleevIntegrationService = class extends Service {
|
|
|
214
229
|
logLevel: resolvedEntry.logLevel
|
|
215
230
|
};
|
|
216
231
|
let configSource = () => entry;
|
|
217
|
-
this.
|
|
232
|
+
this.logger = getPluginLogger({
|
|
233
|
+
pluginId: "dsh-sleev",
|
|
234
|
+
level: pluginLogLevel(resolvedEntry.logLevel),
|
|
235
|
+
console: "trace",
|
|
236
|
+
consoleSink: createHostLoggerSink(ctx.logger)
|
|
237
|
+
});
|
|
238
|
+
ctx.effect(() => async () => this.logger.close(), "dsh-sleev.logger");
|
|
239
|
+
this.telemetry = new CallTelemetryStore(this.logger.child("telemetry"), () => resolveConfig(configSource()));
|
|
218
240
|
installSettingsSection(ctx, SLEEV_SETTINGS_NAMESPACE, ConfigSchema, entry, {
|
|
219
241
|
setSource: (current) => {
|
|
220
242
|
configSource = current;
|
|
221
243
|
},
|
|
222
|
-
onChange: () =>
|
|
244
|
+
onChange: () => {
|
|
245
|
+
const config = this.telemetry.reconfigure();
|
|
246
|
+
this.logger.setLevel(pluginLogLevel(config.logLevel));
|
|
247
|
+
this.logger.info("telemetry.config.updated", {
|
|
248
|
+
logLevel: config.logLevel,
|
|
249
|
+
maxRecentCalls: config.maxRecentCalls
|
|
250
|
+
});
|
|
251
|
+
}
|
|
223
252
|
});
|
|
224
253
|
ctx.on("llm/stream", (options, next) => {
|
|
225
254
|
const config = resolveConfig(configSource());
|
|
@@ -227,10 +256,10 @@ var SleevIntegrationService = class extends Service {
|
|
|
227
256
|
const handle = this.telemetry.begin(options, classifyRequest(options));
|
|
228
257
|
return observeStream(next(), handle);
|
|
229
258
|
}, { global: true });
|
|
230
|
-
if (resolvedEntry.logLevel !== "off")
|
|
259
|
+
if (resolvedEntry.logLevel !== "off") this.logger.info("plugin.ready", {
|
|
231
260
|
routes: resolvedEntry.routes,
|
|
232
261
|
routePrefixes: resolvedEntry.routePrefixes
|
|
233
|
-
})
|
|
262
|
+
});
|
|
234
263
|
}
|
|
235
264
|
/** Bounded completed-call snapshot; no prompts, headers, or credentials. */
|
|
236
265
|
listRecentCalls() {
|
|
@@ -3,8 +3,8 @@ import type { ResolvedConfig } from "../shared/config.js";
|
|
|
3
3
|
import type { CallResult, OptimizerCallTelemetry, RequestKind } from "../shared/telemetry.js";
|
|
4
4
|
/** Minimal logger face used by Cordis and isolated unit tests. */
|
|
5
5
|
export interface TelemetryLogger {
|
|
6
|
-
debug(
|
|
7
|
-
info(
|
|
6
|
+
debug(event: string, fields?: Record<string, unknown>): void;
|
|
7
|
+
info(event: string, fields?: Record<string, unknown>): void;
|
|
8
8
|
}
|
|
9
9
|
/** Mutable handle kept only for the duration of a streaming call. */
|
|
10
10
|
export interface CallHandle {
|
package/lib/types/index.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export declare class SleevIntegrationService extends Service {
|
|
|
14
14
|
static inject: string[];
|
|
15
15
|
static Config: import("@deepseek-ai/schemastery").default<Config>;
|
|
16
16
|
private readonly telemetry;
|
|
17
|
+
private readonly logger;
|
|
17
18
|
constructor(ctx: Context, input?: Config);
|
|
18
19
|
/** Bounded completed-call snapshot; no prompts, headers, or credentials. */
|
|
19
20
|
listRecentCalls(): readonly OptimizerCallTelemetry[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yadsh/dsh-sleev",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "Sleev routing observability for DeepSeek Harness",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -55,22 +55,6 @@
|
|
|
55
55
|
"README.zh-CN.md",
|
|
56
56
|
"LICENSE"
|
|
57
57
|
],
|
|
58
|
-
"scripts": {
|
|
59
|
-
"clean": "node -e \"require('node:fs').rmSync('lib', { recursive: true, force: true })\"",
|
|
60
|
-
"lint": "eslint src tests scripts",
|
|
61
|
-
"format": "prettier --check . --end-of-line auto",
|
|
62
|
-
"format:write": "prettier --write . --end-of-line auto",
|
|
63
|
-
"typecheck": "tsc --noEmit",
|
|
64
|
-
"test": "vitest run",
|
|
65
|
-
"test:package": "node scripts/verify-package.mjs",
|
|
66
|
-
"verify": "pnpm run test:package",
|
|
67
|
-
"smoke:packed": "node scripts/smoke-packed-dsh.mjs",
|
|
68
|
-
"build": "pnpm run clean && tsdown && tsc -p tsconfig.build.json",
|
|
69
|
-
"smoke:neuraldeep": "tsx scripts/smoke-neuraldeep.ts",
|
|
70
|
-
"check": "pnpm run format && pnpm run typecheck && pnpm run test && pnpm run build && pnpm run test:package",
|
|
71
|
-
"prepare": "tsdown && tsc -p tsconfig.build.json",
|
|
72
|
-
"prepublishOnly": "pnpm run check"
|
|
73
|
-
},
|
|
74
58
|
"keywords": [
|
|
75
59
|
"deepseek",
|
|
76
60
|
"deepseek-harness",
|
|
@@ -84,41 +68,57 @@
|
|
|
84
68
|
"node": "^22.19.0 || >=24.0.0"
|
|
85
69
|
},
|
|
86
70
|
"peerDependencies": {
|
|
87
|
-
"@deepseek-ai/cordis": "
|
|
88
|
-
"@deepseek-ai/schemastery": "
|
|
89
|
-
"@deepseek-ai/dsh-client-locale": "
|
|
90
|
-
"@deepseek-ai/dsh-client-runtime": "
|
|
91
|
-
"@deepseek-ai/dsh-client-ui-settings": "
|
|
92
|
-
"@deepseek-ai/dsh-client-ui-settings-plugins": "
|
|
93
|
-
"@deepseek-ai/dsh-client-ui-slots": "
|
|
94
|
-
"@deepseek-ai/dsh-llm": "
|
|
95
|
-
"@deepseek-ai/dsh-settings": "
|
|
71
|
+
"@deepseek-ai/cordis": "^4.0.1",
|
|
72
|
+
"@deepseek-ai/schemastery": "^3.18.1",
|
|
73
|
+
"@deepseek-ai/dsh-client-locale": ">=0.1.1-rc.2 <0.2.0",
|
|
74
|
+
"@deepseek-ai/dsh-client-runtime": ">=0.1.1-rc.2 <0.2.0",
|
|
75
|
+
"@deepseek-ai/dsh-client-ui-settings": ">=0.1.1-rc.2 <0.2.0",
|
|
76
|
+
"@deepseek-ai/dsh-client-ui-settings-plugins": ">=0.1.1-rc.2 <0.2.0",
|
|
77
|
+
"@deepseek-ai/dsh-client-ui-slots": ">=0.1.1-rc.2 <0.2.0",
|
|
78
|
+
"@deepseek-ai/dsh-llm": ">=0.1.1-rc.2 <0.2.0",
|
|
79
|
+
"@deepseek-ai/dsh-settings": ">=0.1.1-rc.2 <0.2.0",
|
|
96
80
|
"react": "^18.2.0"
|
|
97
81
|
},
|
|
98
|
-
"dependencies": {
|
|
82
|
+
"dependencies": {
|
|
83
|
+
"@yadsh/dsh-plugin-log": "^0.2.0"
|
|
84
|
+
},
|
|
99
85
|
"devDependencies": {
|
|
100
|
-
"@deepseek-ai/cordis": "
|
|
101
|
-
"@deepseek-ai/schemastery": "
|
|
102
|
-
"@deepseek-ai/dsh-client-locale": "
|
|
103
|
-
"@deepseek-ai/dsh-client-runtime": "
|
|
104
|
-
"@deepseek-ai/dsh-client-ui-settings": "
|
|
105
|
-
"@deepseek-ai/dsh-client-ui-settings-plugins": "
|
|
106
|
-
"@deepseek-ai/dsh-client-ui-slots": "
|
|
107
|
-
"@deepseek-ai/dsh-llm": "
|
|
108
|
-
"@deepseek-ai/dsh-llm-pi-ai": "
|
|
109
|
-
"@deepseek-ai/dsh-settings": "
|
|
110
|
-
"@types/node": "
|
|
111
|
-
"@types/react": "
|
|
112
|
-
"eslint": "
|
|
113
|
-
"prettier": "
|
|
114
|
-
"react": "
|
|
115
|
-
"tsdown": "
|
|
86
|
+
"@deepseek-ai/cordis": "4.0.1",
|
|
87
|
+
"@deepseek-ai/schemastery": "3.18.1",
|
|
88
|
+
"@deepseek-ai/dsh-client-locale": "0.1.1-rc.2",
|
|
89
|
+
"@deepseek-ai/dsh-client-runtime": "0.1.1-rc.2",
|
|
90
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.1.1-rc.2",
|
|
91
|
+
"@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.1-rc.2",
|
|
92
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.1.1-rc.2",
|
|
93
|
+
"@deepseek-ai/dsh-llm": "0.1.1-rc.2",
|
|
94
|
+
"@deepseek-ai/dsh-llm-pi-ai": "0.1.1-rc.2",
|
|
95
|
+
"@deepseek-ai/dsh-settings": "0.1.1-rc.2",
|
|
96
|
+
"@types/node": "^26.4.0",
|
|
97
|
+
"@types/react": "18.3.28",
|
|
98
|
+
"eslint": "10.9.1",
|
|
99
|
+
"prettier": "^3.6.2",
|
|
100
|
+
"react": "18.3.1",
|
|
101
|
+
"tsdown": "^0.22.14",
|
|
116
102
|
"tsx": "4.22.4",
|
|
117
|
-
"typescript": "
|
|
118
|
-
"vitest": "
|
|
103
|
+
"typescript": "^7.0.2",
|
|
104
|
+
"vitest": "^4.1.11"
|
|
119
105
|
},
|
|
120
106
|
"publishConfig": {
|
|
121
107
|
"access": "public",
|
|
122
108
|
"registry": "https://registry.npmjs.org/"
|
|
109
|
+
},
|
|
110
|
+
"scripts": {
|
|
111
|
+
"clean": "node -e \"require('node:fs').rmSync('lib', { recursive: true, force: true })\"",
|
|
112
|
+
"lint": "eslint src tests scripts",
|
|
113
|
+
"format": "prettier --check . --end-of-line auto",
|
|
114
|
+
"format:write": "prettier --write . --end-of-line auto",
|
|
115
|
+
"typecheck": "tsc --noEmit",
|
|
116
|
+
"test": "vitest run",
|
|
117
|
+
"test:package": "node scripts/verify-package.mjs",
|
|
118
|
+
"verify": "pnpm run test:package",
|
|
119
|
+
"smoke:packed": "node scripts/smoke-packed-dsh.mjs",
|
|
120
|
+
"build": "pnpm run clean && tsdown && tsc -p tsconfig.build.json",
|
|
121
|
+
"smoke:neuraldeep": "tsx scripts/smoke-neuraldeep.ts",
|
|
122
|
+
"check": "pnpm run format && pnpm run typecheck && pnpm run test && pnpm run build && pnpm run test:package"
|
|
123
123
|
}
|
|
124
|
-
}
|
|
124
|
+
}
|