@lmzhen/dsh-evolution-settings-ui 0.27.1 → 0.27.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/README.md
CHANGED
|
@@ -63,6 +63,13 @@ escaping as an unhandled rejection. `settle.ts` holds that one verdict function
|
|
|
63
63
|
uses; an unavailable preview prints the host's reason. A late answer for a row the reader already left is
|
|
64
64
|
dropped rather than painted under another row's heading.
|
|
65
65
|
|
|
66
|
+
## The diagnostics card
|
|
67
|
+
|
|
68
|
+
One card in the same section is the read-only **self-check** (`data-card="diagnostics"`): it renders the Host's `DiagnosticsView` runtime window — the same rows the CLI and `/api/dsh-evolution/diagnostics` answer — and owns no key list and no status vocabulary. The view's documentation facts are a CLI/JSON concern and are deliberately not rendered here: a settings page carries the runtime reading, not a spec sheet.
|
|
69
|
+
|
|
70
|
+
It leads with a plain-language verdict derived from the frozen runtime statuses (`运行正常` / `{n} 项需要注意` / `{n} 项异常` / `{n} 项待确认`, decided fail > warn > unknown > ok), then renders **运行状态** rows (status dot and word, detail line, remedy line).
|
|
71
|
+
|
|
72
|
+
The card is collapsible with the same `.evolution-param-head` button and body inset as the parameter cards; Refresh is an explicit control in the body (one read on mount, one per click), and a failed read renders the shared failure block with the `/evolution doctor` command fallback.
|
|
66
73
|
## A seat that arrives late revives the card
|
|
67
74
|
|
|
68
75
|
The seat is probed lazily (never captured at apply time), but probing alone only answers the NEXT read —
|
package/lib/client.js
CHANGED
|
@@ -1069,12 +1069,15 @@ window.__ModuleLoader__.load({
|
|
|
1069
1069
|
//#endregion
|
|
1070
1070
|
//#region src/client/DiagnosticsCard.ts
|
|
1071
1071
|
/**
|
|
1072
|
-
* The diagnostics card (W7 S7): the
|
|
1072
|
+
* The diagnostics card (W7 S7): the settings face of the SAME DiagnosticsView the CLI and the
|
|
1073
1073
|
* `/api/dsh-evolution/diagnostics` route answer.
|
|
1074
1074
|
*
|
|
1075
1075
|
* Read-only by construction: it fetches once on mount and only refetches on an explicit Refresh; a
|
|
1076
|
-
* failed read renders the shared FailureBlock with the command-face fallback.
|
|
1077
|
-
*
|
|
1076
|
+
* failed read renders the shared FailureBlock with the command-face fallback. The client owns no
|
|
1077
|
+
* key list and no status vocabulary: it renders the host view's frozen runtime rows and leads with
|
|
1078
|
+
* a plain-language summary. The view's documentation facts are a CLI/JSON concern and are
|
|
1079
|
+
* deliberately NOT rendered here (0.27.2 real-machine feedback: a settings page is not a spec
|
|
1080
|
+
* sheet; the runtime window is the whole reading).
|
|
1078
1081
|
* @module @lmzhen/dsh-evolution-settings-ui/client/DiagnosticsCard
|
|
1079
1082
|
*/
|
|
1080
1083
|
/** Which word one status gets (the frozen W1 status set). */
|
|
@@ -1084,6 +1087,32 @@ window.__ModuleLoader__.load({
|
|
|
1084
1087
|
fail: "diagStatusFail",
|
|
1085
1088
|
unknown: "diagStatusUnknown"
|
|
1086
1089
|
});
|
|
1090
|
+
/** The summary word for a badge status (the same frozen set; ok has no count). */
|
|
1091
|
+
const SUMMARY_KEYS = Object.freeze({
|
|
1092
|
+
ok: "diagSummaryOk",
|
|
1093
|
+
warn: "diagSummaryWarn",
|
|
1094
|
+
fail: "diagSummaryFail",
|
|
1095
|
+
unknown: "diagSummaryUnknown"
|
|
1096
|
+
});
|
|
1097
|
+
/** The one status the card leads with: fail > warn > unknown > ok. */
|
|
1098
|
+
function summaryOf(rows) {
|
|
1099
|
+
const count = (status) => rows.filter((row) => row.status === status).length;
|
|
1100
|
+
for (const status of [
|
|
1101
|
+
"fail",
|
|
1102
|
+
"warn",
|
|
1103
|
+
"unknown"
|
|
1104
|
+
]) {
|
|
1105
|
+
const n = count(status);
|
|
1106
|
+
if (n > 0) return {
|
|
1107
|
+
status,
|
|
1108
|
+
count: n
|
|
1109
|
+
};
|
|
1110
|
+
}
|
|
1111
|
+
return {
|
|
1112
|
+
status: "ok",
|
|
1113
|
+
count: 0
|
|
1114
|
+
};
|
|
1115
|
+
}
|
|
1087
1116
|
/**
|
|
1088
1117
|
* Render the card.
|
|
1089
1118
|
* @param props - the copy seat, the host call and the command fallback.
|
|
@@ -1093,6 +1122,7 @@ window.__ModuleLoader__.load({
|
|
|
1093
1122
|
const { t, api } = props;
|
|
1094
1123
|
const translate = (key, values) => t(key, values);
|
|
1095
1124
|
const [state, setState] = (0, react.useState)({ phase: "loading" });
|
|
1125
|
+
const [open, setOpen] = (0, react.useState)(true);
|
|
1096
1126
|
const ticket = (0, react.useRef)(0);
|
|
1097
1127
|
const read = (keepView) => {
|
|
1098
1128
|
const current = ticket.current + 1;
|
|
@@ -1115,12 +1145,24 @@ window.__ModuleLoader__.load({
|
|
|
1115
1145
|
const refresh = () => {
|
|
1116
1146
|
read(true);
|
|
1117
1147
|
};
|
|
1118
|
-
const
|
|
1148
|
+
const summary = state.phase === "ready" ? summaryOf(state.view.runtime) : void 0;
|
|
1149
|
+
const header = (0, react.createElement)("button", {
|
|
1119
1150
|
type: "button",
|
|
1120
|
-
className: "evolution-param-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1151
|
+
className: "evolution-param-head",
|
|
1152
|
+
"aria-expanded": open ? "true" : "false",
|
|
1153
|
+
onClick: () => {
|
|
1154
|
+
setOpen(!open);
|
|
1155
|
+
}
|
|
1156
|
+
}, (0, react.createElement)("span", { className: "evolution-param-card-title" }, t("diagTitle")), summary === void 0 ? null : (0, react.createElement)("span", {
|
|
1157
|
+
className: "evo-diag-badge",
|
|
1158
|
+
"data-status": summary.status
|
|
1159
|
+
}, t(SUMMARY_KEYS[summary.status], summary.count === 0 ? void 0 : { n: summary.count })), (0, react.createElement)("span", { className: "evolution-param-chevron" }, open ? "▲" : "▼"));
|
|
1160
|
+
const runtime = (view) => view.runtime.length === 0 ? null : (0, react.createElement)("div", {}, (0, react.createElement)("h3", { className: "evolution-param-group" }, t("diagRuntimeTitle")), (0, react.createElement)("div", { className: "evo-diag-list" }, ...view.runtime.map((row) => (0, react.createElement)("div", {
|
|
1161
|
+
key: "runtime-" + row.key,
|
|
1162
|
+
className: "evo-diag-item",
|
|
1163
|
+
"data-kind": "runtime",
|
|
1164
|
+
"data-status": row.status
|
|
1165
|
+
}, (0, react.createElement)("div", { className: "evo-diag-row-head" }, (0, react.createElement)("span", { className: "evo-diag-dot" }), (0, react.createElement)("span", { className: "evo-diag-label" }, row.label), (0, react.createElement)("span", { className: "evo-diag-status" }, t(STATUS_KEYS[row.status]))), row.detail === void 0 ? null : (0, react.createElement)("span", { className: "evo-diag-detail" }, row.detail), row.remedy === void 0 ? null : (0, react.createElement)("span", { className: "evo-diag-remedy" }, t("diagRemedy") + row.remedy)))));
|
|
1124
1166
|
const body = () => {
|
|
1125
1167
|
if (state.phase === "loading") return (0, react.createElement)("p", { className: "evolution-param-loading" }, t("stateLoading"));
|
|
1126
1168
|
if (state.phase === "failed") return FailureBlock({
|
|
@@ -1129,23 +1171,17 @@ window.__ModuleLoader__.load({
|
|
|
1129
1171
|
fallback: props.fallback
|
|
1130
1172
|
});
|
|
1131
1173
|
const view = state.view;
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
className: "
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
key: "runtime-" + row.key,
|
|
1139
|
-
className: "evo-diag-row",
|
|
1140
|
-
"data-kind": "runtime",
|
|
1141
|
-
"data-status": row.status
|
|
1142
|
-
}, (0, react.createElement)("span", { className: "evo-diag-key" }, row.label), (0, react.createElement)("span", { className: "evo-diag-status" }, t(STATUS_KEYS[row.status])), row.detail === void 0 ? null : (0, react.createElement)("span", { className: "evo-diag-detail" }, row.detail), row.remedy === void 0 ? null : (0, react.createElement)("span", { className: "evo-diag-remedy" }, t("diagRemedy") + row.remedy)));
|
|
1143
|
-
return (0, react.createElement)("div", { className: "evo-diag-body" }, (0, react.createElement)("p", { className: "evolution-params-subtitle" }, t("diagSubtitle")), (0, react.createElement)("p", { className: "evo-diag-meta" }, t("diagSchema", { n: view.schemaVersion }) + " · " + t("diagGeneratedAt", { at: view.generatedAt })), (0, react.createElement)("h3", { className: "evo-diag-section" }, t("diagFactsTitle")), ...factRows, (0, react.createElement)("h3", { className: "evo-diag-section" }, t("diagRuntimeTitle")), ...runtimeRows);
|
|
1174
|
+
return (0, react.createElement)("div", {}, (0, react.createElement)("p", { className: "evolution-param-note" }, t("diagSubtitle")), (0, react.createElement)("div", { className: "evolution-param-actions" }, (0, react.createElement)("button", {
|
|
1175
|
+
type: "button",
|
|
1176
|
+
className: "evolution-param-button",
|
|
1177
|
+
onClick: refresh,
|
|
1178
|
+
"data-action": "diag-refresh"
|
|
1179
|
+
}, t("diagRefresh"))), runtime(view), view.runtime.length === 0 ? (0, react.createElement)("p", { className: "evolution-param-note" }, t("diagNoRows")) : null);
|
|
1144
1180
|
};
|
|
1145
|
-
return (0, react.createElement)("
|
|
1181
|
+
return (0, react.createElement)("section", {
|
|
1146
1182
|
className: "evolution-param-card",
|
|
1147
1183
|
"data-card": "diagnostics"
|
|
1148
|
-
}, header, body());
|
|
1184
|
+
}, header, open ? (0, react.createElement)("div", { className: "evolution-param-body" }, body()) : null);
|
|
1149
1185
|
}
|
|
1150
1186
|
//#endregion
|
|
1151
1187
|
//#region src/client/diagnostics-state.ts
|
|
@@ -1256,19 +1292,20 @@ window.__ModuleLoader__.load({
|
|
|
1256
1292
|
approvalDiffRemoved: "{n} 行删除",
|
|
1257
1293
|
approvalDiffCut: "改动区域已截断",
|
|
1258
1294
|
diagTitle: "诊断",
|
|
1259
|
-
diagSubtitle: "
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1295
|
+
diagSubtitle: "运行状态的只读自查;不会改动任何东西。",
|
|
1296
|
+
diagRuntimeTitle: "运行状态",
|
|
1297
|
+
diagSummaryOk: "运行正常",
|
|
1298
|
+
diagSummaryWarn: "{n} 项需要注意",
|
|
1299
|
+
diagSummaryFail: "{n} 项异常",
|
|
1300
|
+
diagSummaryUnknown: "{n} 项待确认",
|
|
1264
1301
|
diagRefresh: "刷新",
|
|
1265
1302
|
diagRefreshing: "刷新中…",
|
|
1266
1303
|
diagStatusOk: "正常",
|
|
1267
1304
|
diagStatusWarn: "注意",
|
|
1268
1305
|
diagStatusFail: "异常",
|
|
1269
1306
|
diagStatusUnknown: "未知",
|
|
1270
|
-
diagRemedy: "
|
|
1271
|
-
|
|
1307
|
+
diagRemedy: "建议:",
|
|
1308
|
+
diagNoRows: "没有可显示的运行状态",
|
|
1272
1309
|
stateLoading: "正在读取…",
|
|
1273
1310
|
failureUnauthorized: "需要登录:重新打开这个页面完成登录后再试。",
|
|
1274
1311
|
failureForbidden: "平台拒绝了这个请求(身份不是 owner)。",
|
|
@@ -1338,19 +1375,20 @@ window.__ModuleLoader__.load({
|
|
|
1338
1375
|
approvalDiffRemoved: "{n} lines removed",
|
|
1339
1376
|
approvalDiffCut: "the changed region is truncated",
|
|
1340
1377
|
diagTitle: "Diagnostics",
|
|
1341
|
-
diagSubtitle: "
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1378
|
+
diagSubtitle: "A read-only check of the runtime state; nothing here changes anything.",
|
|
1379
|
+
diagRuntimeTitle: "Runtime status",
|
|
1380
|
+
diagSummaryOk: "All healthy",
|
|
1381
|
+
diagSummaryWarn: "{n} need attention",
|
|
1382
|
+
diagSummaryFail: "{n} failing",
|
|
1383
|
+
diagSummaryUnknown: "{n} unconfirmed",
|
|
1346
1384
|
diagRefresh: "Refresh",
|
|
1347
1385
|
diagRefreshing: "refreshing…",
|
|
1348
|
-
diagStatusOk: "
|
|
1349
|
-
diagStatusWarn: "
|
|
1350
|
-
diagStatusFail: "
|
|
1386
|
+
diagStatusOk: "healthy",
|
|
1387
|
+
diagStatusWarn: "needs attention",
|
|
1388
|
+
diagStatusFail: "failing",
|
|
1351
1389
|
diagStatusUnknown: "unknown",
|
|
1352
|
-
diagRemedy: "
|
|
1353
|
-
|
|
1390
|
+
diagRemedy: "Suggested: ",
|
|
1391
|
+
diagNoRows: "no runtime status to show",
|
|
1354
1392
|
stateLoading: "reading…",
|
|
1355
1393
|
failureUnauthorized: "Sign-in is required: reopen this page and sign in, then retry.",
|
|
1356
1394
|
failureForbidden: "The platform refused this request (not the owner principal).",
|
|
@@ -2027,7 +2065,7 @@ window.__ModuleLoader__.load({
|
|
|
2027
2065
|
* @returns the section element.
|
|
2028
2066
|
*/
|
|
2029
2067
|
function SettingsSection(face) {
|
|
2030
|
-
return (0, react.createElement)("div", { className: "evolution-params" }, (0, react.createElement)("h2", { className: "evolution-params-title" }, face.t("title")), (0, react.createElement)("p", { className: "evolution-params-subtitle" }, face.t("subtitle")), (0, react.createElement)("p", { className: "evolution-params-about" }, "0.
|
|
2068
|
+
return (0, react.createElement)("div", { className: "evolution-params" }, (0, react.createElement)("h2", { className: "evolution-params-title" }, face.t("title")), (0, react.createElement)("p", { className: "evolution-params-subtitle" }, face.t("subtitle")), (0, react.createElement)("p", { className: "evolution-params-about" }, "0.27.3 · Web settings cards for the evolution family's parameter namespaces"), (0, react.createElement)("div", {
|
|
2031
2069
|
key: PENDING_CARD_KEY,
|
|
2032
2070
|
className: "evolution-params-group"
|
|
2033
2071
|
}, face.renderSlot(CARD_SLOT, {}, { entryKey: PENDING_CARD_KEY })), (0, react.createElement)("div", {
|
|
@@ -2119,7 +2157,26 @@ window.__ModuleLoader__.load({
|
|
|
2119
2157
|
".evolution-param-fact+.evolution-param-fact::before{content:\"·\";margin:0 var(--evo-space-6);color:var(--dsw-alias-label-tertiary)}",
|
|
2120
2158
|
".evolution-param-diff{margin:0;padding:var(--evo-space-12) var(--evo-space-16);max-height:var(--evo-cap-block);overflow:auto;border:var(--evo-hairline-width) solid var(--dsw-alias-border-l1);border-radius:var(--evo-radius-surface);background:var(--dsw-alias-markdown-code-block);color:var(--dsw-alias-label-primary);font:var(--dsw-font-markdown-code-block-small);white-space:pre-wrap}",
|
|
2121
2159
|
".evolution-param-line-add{color:var(--evo-tone-success)}",
|
|
2122
|
-
".evolution-param-line-del{color:var(--evo-tone-danger)}"
|
|
2160
|
+
".evolution-param-line-del{color:var(--evo-tone-danger)}",
|
|
2161
|
+
".evolution-param-loading{margin:var(--evo-space-12) 0 0;color:var(--dsw-alias-label-tertiary);font-size:var(--evo-type-xs);line-height:var(--evo-leading-base)}",
|
|
2162
|
+
".evo-diag-badge{display:inline-flex;align-items:center;height:var(--evo-space-20);padding:0 var(--evo-space-8);border-radius:var(--evo-radius-chip);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-secondary);font-size:var(--evo-type-xs);line-height:var(--evo-space-20);flex:none}",
|
|
2163
|
+
".evo-diag-badge[data-status=\"ok\"]{color:var(--dsw-alias-state-success-primary)}",
|
|
2164
|
+
".evo-diag-badge[data-status=\"warn\"]{color:var(--dsw-alias-state-warn-primary)}",
|
|
2165
|
+
".evo-diag-badge[data-status=\"fail\"]{color:var(--dsw-alias-state-error-primary)}",
|
|
2166
|
+
".evo-diag-badge[data-status=\"unknown\"]{color:var(--dsw-alias-state-idle-primary)}",
|
|
2167
|
+
".evo-diag-list{display:flex;flex-direction:column}",
|
|
2168
|
+
".evo-diag-item{padding:var(--evo-space-12) 0}",
|
|
2169
|
+
".evo-diag-item+.evo-diag-item{border-top:var(--evo-hairline-width) solid var(--dsw-alias-border-l2)}",
|
|
2170
|
+
".evo-diag-label{display:block;color:var(--dsw-alias-label-tertiary);font-size:var(--evo-type-xs);line-height:var(--evo-leading-base)}",
|
|
2171
|
+
".evo-diag-row-head{display:flex;align-items:baseline;gap:var(--evo-space-6);flex-wrap:wrap}",
|
|
2172
|
+
".evo-diag-dot{width:var(--evo-space-6);height:var(--evo-space-6);border-radius:var(--evo-radius-pill);background:var(--evo-diag-tone,var(--dsw-alias-state-idle-primary));flex:none}",
|
|
2173
|
+
".evo-diag-status{color:var(--evo-diag-tone,var(--dsw-alias-state-idle-primary));font-size:var(--evo-type-xs);line-height:var(--evo-leading-base)}",
|
|
2174
|
+
".evo-diag-item[data-status=\"ok\"]{--evo-diag-tone:var(--dsw-alias-state-success-primary)}",
|
|
2175
|
+
".evo-diag-item[data-status=\"warn\"]{--evo-diag-tone:var(--dsw-alias-state-warn-primary)}",
|
|
2176
|
+
".evo-diag-item[data-status=\"fail\"]{--evo-diag-tone:var(--dsw-alias-state-error-primary)}",
|
|
2177
|
+
".evo-diag-item[data-status=\"unknown\"]{--evo-diag-tone:var(--dsw-alias-state-idle-primary)}",
|
|
2178
|
+
".evo-diag-detail{display:block;margin:var(--evo-space-2) 0 0;color:var(--dsw-alias-label-secondary);font-size:var(--evo-type-xs);line-height:var(--evo-leading-base);overflow-wrap:anywhere}",
|
|
2179
|
+
".evo-diag-remedy{display:block;margin:var(--evo-space-4) 0 0;color:var(--dsw-alias-label-tertiary);font-size:var(--evo-type-xs);line-height:var(--evo-leading-base)}"
|
|
2123
2180
|
].join("\n");
|
|
2124
2181
|
/**
|
|
2125
2182
|
* Inject the stylesheet once per document.
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The diagnostics card (W7 S7): the
|
|
2
|
+
* The diagnostics card (W7 S7): the settings face of the SAME DiagnosticsView the CLI and the
|
|
3
3
|
* `/api/dsh-evolution/diagnostics` route answer.
|
|
4
4
|
*
|
|
5
5
|
* Read-only by construction: it fetches once on mount and only refetches on an explicit Refresh; a
|
|
6
|
-
* failed read renders the shared FailureBlock with the command-face fallback.
|
|
7
|
-
*
|
|
6
|
+
* failed read renders the shared FailureBlock with the command-face fallback. The client owns no
|
|
7
|
+
* key list and no status vocabulary: it renders the host view's frozen runtime rows and leads with
|
|
8
|
+
* a plain-language summary. The view's documentation facts are a CLI/JSON concern and are
|
|
9
|
+
* deliberately NOT rendered here (0.27.2 real-machine feedback: a settings page is not a spec
|
|
10
|
+
* sheet; the runtime window is the whole reading).
|
|
8
11
|
* @module @lmzhen/dsh-evolution-settings-ui/client/DiagnosticsCard
|
|
9
12
|
*/
|
|
10
13
|
import { type ReactNode } from 'react';
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* description, so the settings surface can state both without a hand-written copy.
|
|
6
6
|
*/
|
|
7
7
|
/** The family version this surface belongs to. */
|
|
8
|
-
export declare const FAMILY_VERSION = "0.
|
|
8
|
+
export declare const FAMILY_VERSION = "0.27.3";
|
|
9
9
|
/** What this surface is for, in one line. */
|
|
10
10
|
export declare const PACKAGE_PURPOSE = "Web settings cards for the evolution family's parameter namespaces";
|
|
11
11
|
//# sourceMappingURL=generated-about.d.ts.map
|
|
@@ -72,19 +72,20 @@ export declare const zh: {
|
|
|
72
72
|
readonly approvalDiffRemoved: "{n} 行删除";
|
|
73
73
|
readonly approvalDiffCut: "改动区域已截断";
|
|
74
74
|
readonly diagTitle: "诊断";
|
|
75
|
-
readonly diagSubtitle: "
|
|
76
|
-
readonly
|
|
77
|
-
readonly
|
|
78
|
-
readonly
|
|
79
|
-
readonly
|
|
75
|
+
readonly diagSubtitle: "运行状态的只读自查;不会改动任何东西。";
|
|
76
|
+
readonly diagRuntimeTitle: "运行状态";
|
|
77
|
+
readonly diagSummaryOk: "运行正常";
|
|
78
|
+
readonly diagSummaryWarn: "{n} 项需要注意";
|
|
79
|
+
readonly diagSummaryFail: "{n} 项异常";
|
|
80
|
+
readonly diagSummaryUnknown: "{n} 项待确认";
|
|
80
81
|
readonly diagRefresh: "刷新";
|
|
81
82
|
readonly diagRefreshing: "刷新中…";
|
|
82
83
|
readonly diagStatusOk: "正常";
|
|
83
84
|
readonly diagStatusWarn: "注意";
|
|
84
85
|
readonly diagStatusFail: "异常";
|
|
85
86
|
readonly diagStatusUnknown: "未知";
|
|
86
|
-
readonly diagRemedy: "
|
|
87
|
-
readonly
|
|
87
|
+
readonly diagRemedy: "建议:";
|
|
88
|
+
readonly diagNoRows: "没有可显示的运行状态";
|
|
88
89
|
readonly stateLoading: "正在读取…";
|
|
89
90
|
readonly failureUnauthorized: "需要登录:重新打开这个页面完成登录后再试。";
|
|
90
91
|
readonly failureForbidden: "平台拒绝了这个请求(身份不是 owner)。";
|
package/package.json
CHANGED