@klarkxy/dsh-git-commit 0.2.5 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/docs/README.zh-CN.md +4 -3
- package/lib/client.inner.cjs +120 -58
- package/lib/client.inner.cjs.map +1 -1
- package/lib/client.js +120 -58
- package/lib/contracts.d.ts +1 -1
- package/lib/index.d.ts +4 -1
- package/lib/index.js +14 -4
- package/lib/index.js.map +1 -1
- package/package.json +21 -11
package/README.md
CHANGED
|
@@ -23,13 +23,14 @@ Replace `web` with your profile name and restart it if DSH asks.
|
|
|
23
23
|
|
|
24
24
|
Under **Plugins → Git Commit** you can choose the **Commit planning model** (empty follows the current session model) and turn on **Commit even without a model plan**, which makes one commit when the model is unavailable.
|
|
25
25
|
|
|
26
|
-
If the model list cannot load, or some providers fail, use **Retry** beside the model picker
|
|
26
|
+
If the model list cannot load, or some providers fail, use **Retry** beside the model picker; your saved model stays selected.
|
|
27
27
|
|
|
28
28
|
## Good to know
|
|
29
29
|
|
|
30
|
-
-
|
|
30
|
+
- The repository follows the conversation's current working directory; changing directories while a commit is being planned stops the run.
|
|
31
|
+
- All uncommitted changes are included, including new files.
|
|
31
32
|
- It only commits; it never pushes.
|
|
32
|
-
- If the run stops partway, finished commits stay and the panel shows what was left
|
|
33
|
+
- If the run stops partway, finished commits stay and the panel shows what was left; nothing is rolled back or retried automatically.
|
|
33
34
|
- The button is unavailable while the session is running.
|
|
34
35
|
|
|
35
36
|
## License
|
package/docs/README.zh-CN.md
CHANGED
|
@@ -21,13 +21,14 @@ dsh plugin --profile web add @klarkxy/dsh-git-commit
|
|
|
21
21
|
3. 确认分支、文件数和模型后提交。
|
|
22
22
|
4. 面板会列出创建的提交。
|
|
23
23
|
|
|
24
|
-
在「插件 → Git
|
|
24
|
+
在「插件 → Git 提交」里可以选择**提交规划模型**(留空跟随当前会话模型),也可以打开**模型不可用时仍然提交**,模型不可用时改为只做一次提交。
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
模型列表加载失败或部分提供商不可用时,可在模型选择器旁点击「重试」;已保存的模型选择会保留。
|
|
27
27
|
|
|
28
28
|
## 注意
|
|
29
29
|
|
|
30
|
-
-
|
|
30
|
+
- 仓库跟随对话当前的工作目录;规划提交期间切换目录会停止本次提交。
|
|
31
|
+
- 会提交仓库里全部未提交的改动,包括新文件。
|
|
31
32
|
- 只提交,不推送。
|
|
32
33
|
- 中途停止时,已完成的提交会保留,面板显示剩余内容;不会自动回滚或重试。
|
|
33
34
|
- 会话运行期间按钮不可用。
|
package/lib/client.inner.cjs
CHANGED
|
@@ -262,7 +262,14 @@ function useModelCatalog(load, options = {}) {
|
|
|
262
262
|
refresh
|
|
263
263
|
};
|
|
264
264
|
}
|
|
265
|
-
/**
|
|
265
|
+
/**
|
|
266
|
+
* Also accepts a mapped state from a caller that owns broader async orchestration.
|
|
267
|
+
*
|
|
268
|
+
* The dsh-ui-* classes carry the styling and resolve through the consuming
|
|
269
|
+
* plugin's own officialUiCss scope (every consumer mounts its root class, so
|
|
270
|
+
* e.g. `.dsh-model-hub .dsh-ui-loading` paints this); dsh-model-catalog-status
|
|
271
|
+
* stays as a structural hook for tests and layout, never a colour source.
|
|
272
|
+
*/
|
|
266
273
|
function ModelCatalogStatus({ state, locale }) {
|
|
267
274
|
const zh = locale?.toLowerCase().startsWith("zh") === true;
|
|
268
275
|
const copy = zh ? {
|
|
@@ -278,15 +285,17 @@ function ModelCatalogStatus({ state, locale }) {
|
|
|
278
285
|
};
|
|
279
286
|
if (!state.loading && !state.error && state.failures.length === 0) return null;
|
|
280
287
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
281
|
-
className: "dsh-model-catalog-status",
|
|
288
|
+
className: "dsh-model-catalog-status dsh-ui-stack",
|
|
282
289
|
lang: zh ? "zh" : "en",
|
|
283
290
|
children: [
|
|
284
291
|
state.loading ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
285
292
|
role: "status",
|
|
293
|
+
className: "dsh-ui-loading",
|
|
286
294
|
children: copy.loading
|
|
287
295
|
}) : null,
|
|
288
296
|
state.error ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
289
297
|
role: "alert",
|
|
298
|
+
className: "dsh-ui-error dsh-ui-wrap",
|
|
290
299
|
children: [
|
|
291
300
|
copy.error,
|
|
292
301
|
": ",
|
|
@@ -295,20 +304,27 @@ function ModelCatalogStatus({ state, locale }) {
|
|
|
295
304
|
}) : null,
|
|
296
305
|
state.failures.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
297
306
|
role: "status",
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
failure.
|
|
302
|
-
|
|
307
|
+
className: "dsh-ui-meta",
|
|
308
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: copy.partial }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
|
|
309
|
+
className: "dsh-ui-list",
|
|
310
|
+
children: state.failures.map((failure, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [
|
|
311
|
+
failure.name || failure.id,
|
|
312
|
+
": ",
|
|
313
|
+
failure.message
|
|
314
|
+
] }, `${failure.id}:${index}`))
|
|
315
|
+
})]
|
|
303
316
|
}) : null,
|
|
304
|
-
state.error || state.failures.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
state.
|
|
310
|
-
|
|
311
|
-
|
|
317
|
+
state.error || state.failures.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
318
|
+
className: "dsh-ui-actions",
|
|
319
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
320
|
+
type: "button",
|
|
321
|
+
size: "sm",
|
|
322
|
+
disabled: state.loading,
|
|
323
|
+
onClick: () => {
|
|
324
|
+
state.refresh();
|
|
325
|
+
},
|
|
326
|
+
children: copy.retry
|
|
327
|
+
})
|
|
312
328
|
}) : null
|
|
313
329
|
]
|
|
314
330
|
});
|
|
@@ -328,7 +344,8 @@ function ModelCatalogStatus({ state, locale }) {
|
|
|
328
344
|
* Sticky group headings, subsequence ranking, highlight walking and focus
|
|
329
345
|
* hand-back all match the host. SYNC POINT: when the host's ModelSelect or
|
|
330
346
|
* ModelSelect.module.css changes, this copy must be re-transcribed; styles
|
|
331
|
-
* below may only reference
|
|
347
|
+
* below may only reference allowlisted theme tokens (the --dsw-* set plus the
|
|
348
|
+
* host's --ds-* motion tokens), never literal colors.
|
|
332
349
|
*
|
|
333
350
|
* It statically imports the primitives, so only browser clients should load
|
|
334
351
|
* this entry; host code and node tests use the core entry (`./index.ts`).
|
|
@@ -836,7 +853,8 @@ function ModelMenu(props) {
|
|
|
836
853
|
* sticky group headings (MenuGroup's own CSS), and the l1-stroke prominent
|
|
837
854
|
* elevation at portal z-index 1100. The trigger mirrors the composer's 28px
|
|
838
855
|
* model pill, chevron rotating open. MenuSurface paints fill and backdrop.
|
|
839
|
-
* Only --dsw
|
|
856
|
+
* Only allowlisted --dsw- and --ds- theme tokens may appear here — a literal
|
|
857
|
+
* color is a bug.
|
|
840
858
|
*/
|
|
841
859
|
const modelMenuCss = `
|
|
842
860
|
.dsh-model-menu-root { min-width: 0; position: relative; display: inline-flex; }
|
|
@@ -859,12 +877,14 @@ const modelMenuCss = `
|
|
|
859
877
|
display: flex;
|
|
860
878
|
}
|
|
861
879
|
.dsh-model-menu-trigger:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); }
|
|
862
|
-
.dsh-model-menu-trigger:focus-visible:not([data-selection-focus]) { box-shadow: 0 0 0
|
|
880
|
+
.dsh-model-menu-trigger:focus-visible:not([data-selection-focus]) { box-shadow: 0 0 0 var(--dsw-focus-ring-width) var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary)); }
|
|
863
881
|
.dsh-model-menu-trigger:disabled { color: var(--dsw-alias-label-dimmed); cursor: default; }
|
|
864
882
|
.dsh-model-menu-triggerLabel { text-overflow: ellipsis; white-space: nowrap; min-width: 0; overflow: hidden; }
|
|
865
883
|
.dsh-model-menu-triggerEffort { text-overflow: ellipsis; white-space: nowrap; min-width: 0; color: var(--dsw-alias-label-caption); flex-shrink: 1000; overflow: hidden; }
|
|
866
|
-
.dsh-model-menu-chevron { color: var(--dsw-alias-label-caption); flex: none; transition: transform
|
|
884
|
+
.dsh-model-menu-chevron { color: var(--dsw-alias-label-caption); flex: none; transition: transform var(--ds-transition-duration) var(--ds-ease-in-out); }
|
|
867
885
|
.dsh-model-menu-chevronOpen { transform: rotate(180deg); }
|
|
886
|
+
/* Portal overlay: the host publishes no z-index token, so the card keeps the
|
|
887
|
+
* native menu layer's 1100 verbatim. */
|
|
868
888
|
.dsh-model-menu-menu {
|
|
869
889
|
z-index: 1100;
|
|
870
890
|
--dsw-elevation-stroke-color: var(--dsw-alias-border-l1);
|
|
@@ -890,6 +910,8 @@ const modelMenuCss = `
|
|
|
890
910
|
.dsh-model-menu-searchWithQuery { padding-right: 34px; }
|
|
891
911
|
.dsh-model-menu-searchRow .dsh-model-menu-search input { padding: 0; font-size: 12px; line-height: normal; }
|
|
892
912
|
.dsh-model-menu-searchRow .dsh-model-menu-search input::placeholder { color: var(--dsw-alias-label-caption); }
|
|
913
|
+
/* The clear button is a circle by geometry (border-radius: 50%), a shape the
|
|
914
|
+
* radius token scale does not describe. */
|
|
893
915
|
.dsh-model-menu-searchClear {
|
|
894
916
|
width: 24px;
|
|
895
917
|
height: 24px;
|
|
@@ -1137,6 +1159,17 @@ ${scope} {
|
|
|
1137
1159
|
/* --- Layout scaffolding. --- */
|
|
1138
1160
|
& .dsh-ui-stack { display: flex; flex-direction: column; gap: 12px; }
|
|
1139
1161
|
& .dsh-ui-stack-lg { display: flex; flex-direction: column; gap: 20px; }
|
|
1162
|
+
/* Plugin detail pages share one reading column. These are layout recipes;
|
|
1163
|
+
* controls keep their own primitive styles. Form spacing follows the host's
|
|
1164
|
+
* settings-form/fields.module.css and SettingsForm.module.css. */
|
|
1165
|
+
& .dsh-ui-page { display: flex; flex-direction: column; gap: 16px; width: 100%; max-width: 760px; min-width: 0; }
|
|
1166
|
+
& .dsh-ui-form { display: flex; flex-direction: column; gap: 0; min-width: 0; }
|
|
1167
|
+
&.dsh-ui-form > .dsh-ui-field, & .dsh-ui-form > .dsh-ui-field { padding: 12px 0; }
|
|
1168
|
+
& .dsh-ui-form-footer { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; padding-top: 16px; min-width: 0; }
|
|
1169
|
+
& .dsh-ui-fields-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 20px; min-width: 0; margin: 0; padding: 0; border: 0; }
|
|
1170
|
+
@media (max-width: 560px) {
|
|
1171
|
+
& .dsh-ui-fields-grid { grid-template-columns: minmax(0, 1fr); }
|
|
1172
|
+
}
|
|
1140
1173
|
& .dsh-ui-row { display: flex; align-items: center; gap: 8px; min-width: 0; }
|
|
1141
1174
|
& .dsh-ui-row-wrap { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
|
|
1142
1175
|
& .dsh-ui-spacer { flex: 1; min-width: 0; }
|
|
@@ -1164,6 +1197,9 @@ ${scope} {
|
|
|
1164
1197
|
* official primitive, so this only owns the vertical rhythm. --- */
|
|
1165
1198
|
& .dsh-ui-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
|
|
1166
1199
|
& .dsh-ui-field + .dsh-ui-field { border-top: 0.5px solid var(--dsw-alias-border-l2); padding-top: 12px; }
|
|
1200
|
+
/* Grid fields share a row, so the stacked-field divider must not win later in
|
|
1201
|
+
* the cascade. Reset it here, after the field recipe. */
|
|
1202
|
+
& .dsh-ui-fields-grid > .dsh-ui-field { padding: 0; border: 0; }
|
|
1167
1203
|
& .dsh-ui-label { display: flex; align-items: center; gap: 6px; font-size: 13px; line-height: 20px; font-weight: 500; color: var(--dsw-alias-label-primary); }
|
|
1168
1204
|
& .dsh-ui-label-row { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
|
|
1169
1205
|
& .dsh-ui-help { font-size: 12px; line-height: 1.6; color: var(--dsw-alias-label-secondary); }
|
|
@@ -1354,29 +1390,22 @@ ${scope} {
|
|
|
1354
1390
|
& *, & *::before, & *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
|
|
1355
1391
|
}
|
|
1356
1392
|
}
|
|
1357
|
-
`.replace(/^& (\.dsh-ui-[a-z0-9-]+)(
|
|
1393
|
+
`.replace(/^& (\.dsh-ui-[a-z0-9-]+)(?=\s*\{)/gm, (_match, className) => `&${className}, & ${className}`);
|
|
1358
1394
|
}
|
|
1359
1395
|
//#endregion
|
|
1360
1396
|
//#region ../dsh-plugin-kit/src/contracts.ts
|
|
1361
|
-
/**
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
method: "watch",
|
|
1374
|
-
mode: "stream",
|
|
1375
|
-
invocation: { kind: "direct" },
|
|
1376
|
-
parameters: [],
|
|
1377
|
-
cancellation: { parameter: "signal" }
|
|
1378
|
-
}]
|
|
1379
|
-
};
|
|
1397
|
+
/** `@klarkxy/dsh-git-commit` becomes `KlarkxyDshGitCommitModelSettingsChanges`. */
|
|
1398
|
+
function modelSettingsChangesIdentity(packageName) {
|
|
1399
|
+
const scoped = /^@([^/]+)\/(.+)$/.exec(packageName);
|
|
1400
|
+
const parts = (scoped ? `${scoped[1]}/${scoped[2]}` : packageName).split(/[^A-Za-z0-9]+/).filter(Boolean);
|
|
1401
|
+
if (!parts.length) throw new Error("Model settings package name has no RPC segment");
|
|
1402
|
+
const segment = `${parts.map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("")}ModelSettingsChanges`;
|
|
1403
|
+
if (!/^[A-Z][A-Za-z0-9]*$/.test(segment)) throw new Error(`Model settings sync name is not an RPC segment: ${segment}`);
|
|
1404
|
+
return {
|
|
1405
|
+
service: segment,
|
|
1406
|
+
namespace: segment
|
|
1407
|
+
};
|
|
1408
|
+
}
|
|
1380
1409
|
//#endregion
|
|
1381
1410
|
//#region ../dsh-plugin-kit/src/model-settings-client.ts
|
|
1382
1411
|
/** This stream carries invalidations only; ready is never a settings snapshot. */
|
|
@@ -1391,17 +1420,44 @@ function parseModelSettingsChangeFrame(value) {
|
|
|
1391
1420
|
};
|
|
1392
1421
|
throw new Error("Invalid model settings change frame");
|
|
1393
1422
|
}
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1423
|
+
/** One owner's contribution. Each package mounts only its own endpoint. */
|
|
1424
|
+
function modelSettingsChangesRemote(packageName, identity = modelSettingsChangesIdentity(packageName)) {
|
|
1425
|
+
return {
|
|
1426
|
+
package: packageName,
|
|
1427
|
+
descriptors: [{
|
|
1428
|
+
id: `${identity.namespace}/watch`,
|
|
1429
|
+
service: identity.service,
|
|
1430
|
+
namespace: identity.namespace,
|
|
1431
|
+
method: "watch",
|
|
1432
|
+
mode: "stream",
|
|
1433
|
+
invocation: { kind: "direct" },
|
|
1434
|
+
parameters: [],
|
|
1435
|
+
cancellation: { parameter: "signal" },
|
|
1436
|
+
result: {
|
|
1437
|
+
mode: "strict",
|
|
1438
|
+
typeSymbol: "ModelSettings.ChangeFrame",
|
|
1439
|
+
create: () => ({ parse: parseModelSettingsChangeFrame })
|
|
1440
|
+
}
|
|
1441
|
+
}]
|
|
1442
|
+
};
|
|
1443
|
+
}
|
|
1444
|
+
/** Mount from a synchronous apply. Disposal waits for an in-flight mount and
|
|
1445
|
+
* then withdraws it, so the contribution cannot outlive the plugin. */
|
|
1446
|
+
function mountModelSettingsChanges(ctx, packageName) {
|
|
1447
|
+
const contribution = modelSettingsChangesRemote(packageName);
|
|
1448
|
+
ctx.inject(["remote"], (injected) => {
|
|
1449
|
+
const scope = injected;
|
|
1450
|
+
const mounting = scope.remote.$mount(contribution);
|
|
1451
|
+
mounting.catch(() => {});
|
|
1452
|
+
scope.effect(() => async () => {
|
|
1453
|
+
await (await mounting.catch(() => void 0))?.();
|
|
1454
|
+
});
|
|
1455
|
+
});
|
|
1456
|
+
}
|
|
1402
1457
|
/** Native RemoteStream owns carrier reconnects; no timers or browser transport.
|
|
1403
1458
|
* A factory shares one logical stream while at least one subscriber remains. */
|
|
1404
|
-
function createModelSettingsSubscriber(ctx,
|
|
1459
|
+
function createModelSettingsSubscriber(ctx, packageName, identity = modelSettingsChangesIdentity(packageName), accept = (ns) => ns === packageName) {
|
|
1460
|
+
const endpoint = identity;
|
|
1405
1461
|
const listeners = /* @__PURE__ */ new Set();
|
|
1406
1462
|
let injection;
|
|
1407
1463
|
let current;
|
|
@@ -1427,12 +1483,18 @@ function createModelSettingsSubscriber(ctx, namespace) {
|
|
|
1427
1483
|
};
|
|
1428
1484
|
const start = () => {
|
|
1429
1485
|
const life = ++lifecycle;
|
|
1430
|
-
injection = ctx.inject(["remote",
|
|
1486
|
+
injection = ctx.inject(["remote", `remote.${endpoint.namespace}`], (injected) => {
|
|
1431
1487
|
if (life !== lifecycle || !listeners.size) return;
|
|
1432
1488
|
const scope = injected;
|
|
1489
|
+
const service = scope.remote[endpoint.namespace];
|
|
1490
|
+
if (!service || !("watch" in service) || !service.watch) {
|
|
1491
|
+
report("Model settings sync service unavailable");
|
|
1492
|
+
return;
|
|
1493
|
+
}
|
|
1494
|
+
const watch = service.watch;
|
|
1433
1495
|
const stream = scope.remote.$stream({
|
|
1434
1496
|
name: "Model settings sync",
|
|
1435
|
-
open: (signal) =>
|
|
1497
|
+
open: (signal) => watch(signal),
|
|
1436
1498
|
ended: (accepted) => /* @__PURE__ */ new Error(`Model settings sync stream ended ${accepted ? "after" : "before"} ready; refresh or reopen the page`)
|
|
1437
1499
|
});
|
|
1438
1500
|
const session = {
|
|
@@ -1467,7 +1529,7 @@ function createModelSettingsSubscriber(ctx, namespace) {
|
|
|
1467
1529
|
invalidate();
|
|
1468
1530
|
} else {
|
|
1469
1531
|
if (!ready) throw new Error("Model settings sync change arrived before ready");
|
|
1470
|
-
if (
|
|
1532
|
+
if (accept(frame.ns)) invalidate();
|
|
1471
1533
|
}
|
|
1472
1534
|
}
|
|
1473
1535
|
} catch (error) {
|
|
@@ -2013,11 +2075,10 @@ const clientCss = `${officialUiCss("gcm-root")}${modelMenuCss}
|
|
|
2013
2075
|
* of at the trigger. Naming both classes puts this rule at the same weight,
|
|
2014
2076
|
* later in the sheet, so it wins. */
|
|
2015
2077
|
.gcm-root.gcm-panel { position: fixed; width: min(360px, calc(100vw - 32px)); max-height: min(560px, calc(100vh - 32px)); overflow: auto; }
|
|
2016
|
-
.gcm-model { display: flex; align-items: center; gap: 6px; min-width: 0; margin: 0; font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-primary); }
|
|
2017
|
-
.gcm-commits { margin: 0; padding-inline-start: 18px; display: grid; gap: 2px; font-size: 12px; line-height: 18px; overflow-wrap: anywhere; }
|
|
2018
|
-
.gcm-commits code { font-size: 12px; background: var(--dsw-alias-bg-layer-2); padding: 0 4px; border-radius: var(--dsw-radius-sm); }
|
|
2019
|
-
.gcm-settings { display: flex; flex-direction: column; gap:
|
|
2020
|
-
.gcm-settings-status { display: flex; flex-direction: column; gap: 4px; }
|
|
2078
|
+
.gcm-root .gcm-model { display: flex; align-items: center; gap: 6px; min-width: 0; margin: 0; font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-primary); }
|
|
2079
|
+
.gcm-root .gcm-commits { margin: 0; padding-inline-start: 18px; display: grid; gap: 2px; font-size: 12px; line-height: 18px; overflow-wrap: anywhere; }
|
|
2080
|
+
.gcm-root .gcm-commits code { font-size: 12px; background: var(--dsw-alias-bg-layer-2); padding: 0 4px; border-radius: var(--dsw-radius-sm); }
|
|
2081
|
+
.gcm-root .gcm-settings-status { display: flex; flex-direction: column; gap: 4px; }
|
|
2021
2082
|
`;
|
|
2022
2083
|
/** Host UI language, following live switches with the host's English fallback. */
|
|
2023
2084
|
function useHostLocale(client) {
|
|
@@ -2179,7 +2240,7 @@ function GitCommitSettingsPanel(props) {
|
|
|
2179
2240
|
text.stale
|
|
2180
2241
|
]);
|
|
2181
2242
|
if (!settings) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
2182
|
-
className: "gcm-root gcm-settings",
|
|
2243
|
+
className: "gcm-root gcm-settings dsh-ui-page",
|
|
2183
2244
|
children: [
|
|
2184
2245
|
error ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2185
2246
|
role: "alert",
|
|
@@ -2212,7 +2273,7 @@ function GitCommitSettingsPanel(props) {
|
|
|
2212
2273
|
const selectedEffort = efforts.find((item) => item.id === (current.reasoningEffort || ""));
|
|
2213
2274
|
const effortName = selectedEffort ? modelMenuEffortLabel(selectedEffort, language) : void 0;
|
|
2214
2275
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
2215
|
-
className: "gcm-root gcm-settings",
|
|
2276
|
+
className: "gcm-root gcm-settings dsh-ui-page",
|
|
2216
2277
|
"data-testid": "git-commit-settings",
|
|
2217
2278
|
children: [
|
|
2218
2279
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -2339,6 +2400,7 @@ function GitCommitSettingsPanel(props) {
|
|
|
2339
2400
|
}
|
|
2340
2401
|
function apply(ctx) {
|
|
2341
2402
|
const client = ctx;
|
|
2403
|
+
mountModelSettingsChanges(ctx, PLUGIN_NAME);
|
|
2342
2404
|
const settingsSubscriber = createModelSettingsSubscriber(ctx, PLUGIN_NAME);
|
|
2343
2405
|
const subscribeSettings = (change, error) => settingsSubscriber.subscribe(change, error);
|
|
2344
2406
|
ctx.provide(GIT_COMMIT_CLIENT_SERVICE, { active: true });
|