dsh-code-server-app 0.3.59 → 0.3.63

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 CHANGED
@@ -660,6 +660,18 @@ function normalizeClaimExtensions(text) {
660
660
  return seen.join(';')
661
661
  }
662
662
 
663
+ /**
664
+ * FIM 停顿毫秒数的归一化(0.3.62):与宿主 lib/fim-adapter.mjs 的 `clampDebounce` **同语义**。
665
+ * 客户端也夹一次的理由:输入框里可以是任何东西(空、负数、10^9),用户在点保存之前就该看到
666
+ * "保存后会变成什么",而不是保存完发现值被宿主悄悄改掉 —— 这与认领类型那行显示"实际规则"同一考虑。
667
+ */
668
+ function normalizeFimDebounce(value) {
669
+ if (value === undefined || value === null || value === '') return 250
670
+ var n = typeof value === 'number' ? value : Number(value)
671
+ if (!isFinite(n)) return 250
672
+ return Math.min(3000, Math.max(100, Math.round(n)))
673
+ }
674
+
663
675
  /**
664
676
  * 解析策略文本。
665
677
  * @param text - 归一化前或后的文本都接受。
@@ -1325,6 +1337,20 @@ let React = require('react')
1325
1337
  React.createElement('span', { className: 'dshcs-hint' }, props.children)
1326
1338
  )
1327
1339
  }
1340
+ /** 数字输入(0.3.62 起,用于"停顿毫秒数"这类有上下限的整数)。
1341
+ * 为什么不用文本框:用户在点保存**之前**就该看到 min/max 这层约束;真正的夹取在
1342
+ * 保存时 `normalizeFimDebounce`(与宿主 clampDebounce 同语义),两者一致才不会"保存后被悄悄改掉"。 */
1343
+ function csNumber(props) {
1344
+ return React.createElement('label', { className: 'dshcs-text' },
1345
+ React.createElement('input', {
1346
+ type: 'number',
1347
+ value: props.value === undefined || props.value === null ? '' : String(props.value),
1348
+ min: props.min, max: props.max, step: props.step === undefined ? 10 : props.step,
1349
+ disabled: props.disabled === true, spellCheck: false, autoComplete: 'off',
1350
+ onChange: function (event) { props.onChange(event.target.value) },
1351
+ })
1352
+ )
1353
+ }
1328
1354
  /** 多行文本输入(0.3.52 起,用于"认领类型"这类清单)。
1329
1355
  * 为什么不是单行 input:0.3.51 之后默认值有 98 条排除项(≈700 字符),单行框只能看到开头,
1330
1356
  * 剩下全靠横向滚动 —— 既看不全也改不动。这里改用 textarea,并**按内容自动长高**(上限 12 行),
@@ -1423,6 +1449,10 @@ let React = require('react')
1423
1449
  keepResident: value.keepResident !== false,
1424
1450
  claimExtensions: typeof value.claimExtensions === 'string' ? value.claimExtensions : DEFAULT_CLAIM_EXTENSIONS,
1425
1451
  fullscreenOnOpen: value.fullscreenOnOpen !== false,
1452
+ fim: value.fim === true,
1453
+ fimDebounceMs: normalizeFimDebounce(value.fimDebounceMs),
1454
+ fimMultiline: value.fimMultiline !== false,
1455
+ fimDisableGlobs: typeof value.fimDisableGlobs === 'string' ? value.fimDisableGlobs : '',
1426
1456
  }
1427
1457
  // ---- 旧版 DSH(无右侧栏服务):本页是唯一的提示出口,不显示任何设置项 ----
1428
1458
  if (liveStore != null && liveStore.sidebarUi === 'legacy') {
@@ -1447,9 +1477,17 @@ let React = require('react')
1447
1477
  var overriddenKeep = user !== undefined && user !== null && Object.prototype.hasOwnProperty.call(user, 'keepResident')
1448
1478
  var overriddenClaim = user !== undefined && user !== null && Object.prototype.hasOwnProperty.call(user, 'claimExtensions')
1449
1479
  var overriddenFullscreen = user !== undefined && user !== null && Object.prototype.hasOwnProperty.call(user, 'fullscreenOnOpen')
1480
+ var overriddenFim = user !== undefined && user !== null && Object.prototype.hasOwnProperty.call(user, 'fim')
1481
+ var overriddenFimDebounce = user !== undefined && user !== null && Object.prototype.hasOwnProperty.call(user, 'fimDebounceMs')
1482
+ var overriddenFimMultiline = user !== undefined && user !== null && Object.prototype.hasOwnProperty.call(user, 'fimMultiline')
1483
+ var overriddenFimGlobs = user !== undefined && user !== null && Object.prototype.hasOwnProperty.call(user, 'fimDisableGlobs')
1450
1484
  var dirty = draft !== null && (draft.keepResident !== loaded.keepResident
1451
1485
  || normalizeClaimExtensions(draft.claimExtensions) !== normalizeClaimExtensions(loaded.claimExtensions)
1452
- || draft.fullscreenOnOpen !== loaded.fullscreenOnOpen)
1486
+ || draft.fullscreenOnOpen !== loaded.fullscreenOnOpen
1487
+ || draft.fim !== loaded.fim
1488
+ || normalizeFimDebounce(draft.fimDebounceMs) !== normalizeFimDebounce(loaded.fimDebounceMs)
1489
+ || draft.fimMultiline !== loaded.fimMultiline
1490
+ || draft.fimDisableGlobs !== loaded.fimDisableGlobs)
1453
1491
  var saveDisabled = !dirty || saving
1454
1492
  var state = {
1455
1493
  available: true,
@@ -1473,6 +1511,10 @@ let React = require('react')
1473
1511
  await props.scope.set('keepResident', d.keepResident === true)
1474
1512
  await props.scope.set('claimExtensions', normalizeClaimExtensions(d.claimExtensions))
1475
1513
  await props.scope.set('fullscreenOnOpen', d.fullscreenOnOpen === true)
1514
+ await props.scope.set('fim', d.fim === true)
1515
+ await props.scope.set('fimDebounceMs', normalizeFimDebounce(d.fimDebounceMs))
1516
+ await props.scope.set('fimMultiline', d.fimMultiline === true)
1517
+ await props.scope.set('fimDisableGlobs', typeof d.fimDisableGlobs === 'string' ? d.fimDisableGlobs : '')
1476
1518
  setDraft(null)
1477
1519
  syncStatusToStore()
1478
1520
  } catch (e) {
@@ -1490,10 +1532,18 @@ let React = require('react')
1490
1532
  await props.scope.unset('keepResident')
1491
1533
  await props.scope.unset('claimExtensions')
1492
1534
  await props.scope.unset('fullscreenOnOpen')
1535
+ await props.scope.unset('fim')
1536
+ await props.scope.unset('fimDebounceMs')
1537
+ await props.scope.unset('fimMultiline')
1538
+ await props.scope.unset('fimDisableGlobs')
1493
1539
  } else {
1494
1540
  await props.scope.set('keepResident', value.keepResident === undefined || value.keepResident === null ? true : value.keepResident)
1495
1541
  await props.scope.set('claimExtensions', typeof value.claimExtensions === 'string' ? normalizeClaimExtensions(value.claimExtensions) : DEFAULT_CLAIM_EXTENSIONS)
1496
1542
  await props.scope.set('fullscreenOnOpen', value.fullscreenOnOpen === undefined || value.fullscreenOnOpen === null ? true : value.fullscreenOnOpen)
1543
+ await props.scope.set('fim', value.fim === true)
1544
+ await props.scope.set('fimDebounceMs', normalizeFimDebounce(value.fimDebounceMs))
1545
+ await props.scope.set('fimMultiline', value.fimMultiline !== false)
1546
+ await props.scope.set('fimDisableGlobs', typeof value.fimDisableGlobs === 'string' ? value.fimDisableGlobs : '')
1497
1547
  }
1498
1548
  setDraft(null)
1499
1549
  syncStatusToStore()
@@ -1503,8 +1553,8 @@ let React = require('react')
1503
1553
  setSaving(false)
1504
1554
  }
1505
1555
  var fields = [
1506
- // 三个设置(0.2.11 起):认领类型 + 打开即全屏 + 后台常驻。入口/依赖安装/环境检测三行已移除
1507
- // (入口在右侧栏「开始」页的 guide 入口框;诊断看 host 日志里的 [code-server] 输出)。
1556
+ // 一行一个可改设置(0.2.11 起):认领类型 + 打开即全屏 + FIM 补全(0.3.61,含 0.3.62 的三个子项)
1557
+ // + 后台常驻。入口/依赖安装/环境检测三行已移除(入口在右侧栏「开始」页的 guide 入口框;诊断看 host 日志)。
1508
1558
  React.createElement('div', { className: 'dshcs-field' },
1509
1559
  React.createElement('div', { className: 'dshcs-fieldHead' },
1510
1560
  React.createElement('span', { className: 'dshcs-fieldLabel' }, '认领类型(按扩展名,分号分隔)'),
@@ -1565,6 +1615,92 @@ let React = require('react')
1565
1615
  '只影响"打开那一刻":切走再切回、再次打开文件 tab 会重新切全屏;'
1566
1616
  + 'DSH 未向插件开放模式接口,本项由点击右侧栏自身的「全屏」按钮实现。')
1567
1617
  ),
1618
+ React.createElement('div', { className: 'dshcs-field' },
1619
+ React.createElement('div', { className: 'dshcs-fieldHead' },
1620
+ React.createElement('span', { className: 'dshcs-fieldLabel' }, 'FIM 补全(实验性)'),
1621
+ overriddenFim === true
1622
+ ? React.createElement(csBadges, {
1623
+ overridden: true, disabled: snapshot.writable !== true,
1624
+ overriddenLabel: '已覆盖', resetLabel: '恢复默认',
1625
+ onReset: function () { doReset() },
1626
+ })
1627
+ : null
1628
+ ),
1629
+ React.createElement(csCheck, {
1630
+ checked: draft !== null ? draft.fim : loaded.fim,
1631
+ disabled: snapshot.writable !== true,
1632
+ onChange: function (v) { setDraft(function (prev) { return Object.assign({}, prev !== null ? prev : loaded, { fim: v === true }) }); setFailed(false) },
1633
+ }, '开启后,在编辑器里打字停顿约 0.3 秒会向模型要一次「续写」,以灰字显示在光标后:Tab 接受、Esc 丢弃。默认关闭'),
1634
+ React.createElement('div', { className: 'dshcs-hint', style: { marginTop: 4 } },
1635
+ '实验性功能,默认关闭。三点须知:'
1636
+ + '① 它是本插件**唯一会把内容发出去**的能力 —— 每次补全会把光标附近的一小段代码(有上限)交给模型,'
1637
+ + '桥的其余部分只读编辑器状态、不外发内容;'
1638
+ + '② 这条调用不计入 DSH 自己的 token 计量(它不是一次会话请求),'
1639
+ + '用量只在 IDE 状态栏的 DSH 项上是可见的;'
1640
+ + '③ 模型偶尔会在"并不需要补"的位置硬凑一段,忽略即可(Esc 或继续打字都会让它消失)。'
1641
+ + '关掉本项后扩展会立刻注销补全 provider,不再发出任何补全请求。')
1642
+ ),
1643
+ React.createElement('div', { className: 'dshcs-field' },
1644
+ React.createElement('div', { className: 'dshcs-fieldHead' },
1645
+ React.createElement('span', { className: 'dshcs-fieldLabel' }, 'FIM · 停顿毫秒数(停下多久才请求)'),
1646
+ overriddenFimDebounce === true
1647
+ ? React.createElement(csBadges, {
1648
+ overridden: true, disabled: snapshot.writable !== true,
1649
+ overriddenLabel: '已覆盖', resetLabel: '恢复默认',
1650
+ onReset: function () { doReset() },
1651
+ })
1652
+ : null
1653
+ ),
1654
+ React.createElement(csNumber, {
1655
+ value: draft !== null ? draft.fimDebounceMs : loaded.fimDebounceMs,
1656
+ min: 100, max: 3000, step: 50, disabled: snapshot.writable !== true,
1657
+ onChange: function (v) { setDraft(function (prev) { return Object.assign({}, prev !== null ? prev : loaded, { fimDebounceMs: v }) }); setFailed(false) },
1658
+ }),
1659
+ React.createElement('div', { className: 'dshcs-hint', style: { marginTop: 4 } },
1660
+ '有效范围 100–3000ms,保存时按它夹取(与宿主同一套规则)。实测这条端点往返 112–416ms,'
1661
+ + '所以停顿基本就是"感知到的延迟":太小会在打字过程中反复触发,太大要等很久才出现灰字。')
1662
+ ),
1663
+ React.createElement('div', { className: 'dshcs-field' },
1664
+ React.createElement('div', { className: 'dshcs-fieldHead' },
1665
+ React.createElement('span', { className: 'dshcs-fieldLabel' }, 'FIM · 允许多行补全'),
1666
+ overriddenFimMultiline === true
1667
+ ? React.createElement(csBadges, {
1668
+ overridden: true, disabled: snapshot.writable !== true,
1669
+ overriddenLabel: '已覆盖', resetLabel: '恢复默认',
1670
+ onReset: function () { doReset() },
1671
+ })
1672
+ : null
1673
+ ),
1674
+ React.createElement(csCheck, {
1675
+ checked: draft !== null ? draft.fimMultiline : loaded.fimMultiline,
1676
+ disabled: snapshot.writable !== true,
1677
+ onChange: function (v) { setDraft(function (prev) { return Object.assign({}, prev !== null ? prev : loaded, { fimMultiline: v === true }) }); setFailed(false) },
1678
+ }, '允许补出多行(关掉后只取第一行;首行为空 = 这次不补)'),
1679
+ React.createElement('div', { className: 'dshcs-hint', style: { marginTop: 4 } },
1680
+ '默认开。实测模型在"并不需要补"的位置会硬凑一段,多行会把这种噪声放大 —— 想更克制就关掉它。')
1681
+ ),
1682
+ React.createElement('div', { className: 'dshcs-field' },
1683
+ React.createElement('div', { className: 'dshcs-fieldHead' },
1684
+ React.createElement('span', { className: 'dshcs-fieldLabel' }, 'FIM · 按 glob 禁用(分号或换行分隔)'),
1685
+ overriddenFimGlobs === true
1686
+ ? React.createElement(csBadges, {
1687
+ overridden: true, disabled: snapshot.writable !== true,
1688
+ overriddenLabel: '已覆盖', resetLabel: '恢复默认',
1689
+ onReset: function () { doReset() },
1690
+ })
1691
+ : null
1692
+ ),
1693
+ React.createElement(csTextarea, {
1694
+ value: draft !== null ? draft.fimDisableGlobs : loaded.fimDisableGlobs,
1695
+ disabled: snapshot.writable !== true,
1696
+ placeholder: '例如 *.md;**/dist/**;vendor/**',
1697
+ onChange: function (v) { setDraft(function (prev) { return Object.assign({}, prev !== null ? prev : loaded, { fimDisableGlobs: v }) }); setFailed(false) },
1698
+ }),
1699
+ React.createElement('div', { className: 'dshcs-hint', style: { marginTop: 4 } },
1700
+ '留空 = 不禁用。语法:`*` 不跨目录、`**` 跨目录、不含 `/` 的模式只匹配文件名、`/` 结尾视作 `/**`。'
1701
+ + '例:`*.md`(所有 Markdown)、`vendor/**`、`**/dist/**`、`**/*.min.js`。'
1702
+ + '两边都会判:扩展侧先判(根本不发请求),宿主侧再判一遍。')
1703
+ ),
1568
1704
  React.createElement('div', { className: 'dshcs-field' },
1569
1705
  React.createElement('div', { className: 'dshcs-fieldHead' },
1570
1706
  React.createElement('span', { className: 'dshcs-fieldLabel' }, '后台常驻(切标签不重载)'),