@ai-wendao/ant 0.4.9 → 0.4.10
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 +2 -2
- package/client.js +43 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,11 +20,11 @@ ANT (AI-native Teams) connects a DeepSeek Harness Desktop profile to its team's
|
|
|
20
20
|
|
|
21
21
|
## 企业精选插件
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
管理员从 npm 官方源的 DSH Bundle 精确版本创建草稿,填写源码、许可证、依赖和安装脚本的审核记录后发布。成员在“企业扩展”总览或“插件”分类查看审核信息和本机状态;发布后可让 DSH 官方插件管理器从 npm 安装目录中的精确版本,无须先由管理员锁定 ANT tarball。ANT 也保留可选的固定 tarball 安装路径。直接安装时,DSH 按 registry/fallback 配置解析依赖,设备间版本可能不同;ANT 不会批准依赖构建脚本,如安装因此中断需按 DSH 提示转到原生插件管理页处理。ANT 目录不控制插件之后的自更新;部分插件可提供自己的更新器,DSH 原生插件管理页也可更换版本。安全撤回版本会停止通过 ANT 目录发起的新安装,但不会自动删除本机副本。范围与限制见[上线边界](../../docs/decisions/2026-10-15-plugin-center-rollout.md)。
|
|
24
24
|
|
|
25
25
|
ANT 自身更新使用单独的已审核安装包。管理员将与 npm 发布一致的 `.tgz` 上传到 ANT 服务端并登记版本;新版 ANT 页面可点击“更新”,DSH 原位替换同名 Bundle 后提示重启。旧版 `@ai-wendao/ant` 用户可打开团队服务的 `/ant-update` 指引,在 DSH“添加插件”中粘贴该安装包地址完成一次性原位更新,无需先卸载或使用终端。此入口只分发 ANT 自身,不启用扩展中心其他插件的一键安装。
|
|
26
26
|
|
|
27
|
-
企业精选是团队推荐目录,不是强制白名单;ANT 不能阻止成员从 DSH
|
|
27
|
+
企业精选是团队推荐目录,不是强制白名单;ANT 不能阻止成员从 DSH 原生插件管理页或插件自身更新器安装其他版本。DSH `0.2.0-rc.2` 本身不自动更新已安装 Bundle;插件可以提供自己的更新操作。ANT 目录只约束它发起的安装,不对本机安装后的版本持续强制管理。上线边界见[待决策记录](../../docs/decisions/2026-10-15-plugin-center-rollout.md)。
|
|
28
28
|
|
|
29
29
|
## Existing `ant` alias installations
|
|
30
30
|
|
package/client.js
CHANGED
|
@@ -227,6 +227,12 @@ window.__ModuleLoader__.load({
|
|
|
227
227
|
? url.href : null
|
|
228
228
|
}
|
|
229
229
|
|
|
230
|
+
function pluginInstallSpec(plugin) {
|
|
231
|
+
if (plugin?.status !== 'published' || typeof plugin.package_name !== 'string'
|
|
232
|
+
|| typeof plugin.version !== 'string' || !plugin.package_name || !plugin.version) return ''
|
|
233
|
+
return approvedPluginArtifactUrl(plugin) || directInstallSpec(plugin)
|
|
234
|
+
}
|
|
235
|
+
|
|
230
236
|
function previouslyInstalledReviewedPlugin(plugin) {
|
|
231
237
|
try { return localStorage.getItem(`${PLUGIN_INSTALL_RECORD_PREFIX}${plugin.id}`) === plugin.artifact_sha256 }
|
|
232
238
|
catch { return false }
|
|
@@ -1596,15 +1602,21 @@ window.__ModuleLoader__.load({
|
|
|
1596
1602
|
useEffect(() => { void refresh() }, [refreshToken])
|
|
1597
1603
|
const install = async (plugin) => {
|
|
1598
1604
|
const artifactUrl = approvedPluginArtifactUrl(plugin)
|
|
1599
|
-
|
|
1605
|
+
const installSpec = pluginInstallSpec(plugin)
|
|
1606
|
+
if (!installSpec || workingId || uncertainId === plugin.id || completedId === plugin.id) return
|
|
1600
1607
|
const manager = remote?.pluginManager
|
|
1601
1608
|
if (typeof manager?.installBundle !== 'function') {
|
|
1602
1609
|
setMessage('当前 DSH 未提供插件安装接口,请联系管理员。')
|
|
1603
1610
|
return
|
|
1604
1611
|
}
|
|
1605
1612
|
const local = bundles.find((bundle) => bundle.name === plugin.package_name && bundle.installed)
|
|
1606
|
-
const
|
|
1607
|
-
|
|
1613
|
+
const localAhead = local?.version && newerVersion(local.version, plugin.version)
|
|
1614
|
+
const action = localAhead ? '回退到团队版本' : local ? local.version === plugin.version ? '重新安装' : '更新' : '安装'
|
|
1615
|
+
const sourceNotice = artifactUrl
|
|
1616
|
+
? 'DSH 将安装 ANT 固定的顶层制品。'
|
|
1617
|
+
: `DSH 将优先从 npm 官方源以 ${installSpec} 安装此精确版本,并按其配置回退 registry;依赖版本可能因设备不同。`
|
|
1618
|
+
const updateNotice = 'ANT 不会批准依赖构建脚本;插件自身的更新器或 DSH 原生管理页之后仍可安装其他版本。'
|
|
1619
|
+
if (!window.confirm(`在这台 DSH ${action}团队审核的 ${plugin.title} ${plugin.version}?${sourceNotice}${updateNotice} 插件将在本机运行,完成后需要完全重启 DSH。`)) return
|
|
1608
1620
|
setWorkingId(plugin.id)
|
|
1609
1621
|
setMessage(`正在安装 ${plugin.title},请不要退出 DSH…`)
|
|
1610
1622
|
try {
|
|
@@ -1613,13 +1625,15 @@ window.__ModuleLoader__.load({
|
|
|
1613
1625
|
const latest = Array.isArray(catalog?.plugins)
|
|
1614
1626
|
? catalog.plugins.find((item) => item.id === plugin.id) : null
|
|
1615
1627
|
if (!response.ok || latest?.package_name !== plugin.package_name
|
|
1616
|
-
|| latest?.version !== plugin.version || latest
|
|
1617
|
-
|| approvedPluginArtifactUrl(latest) !== artifactUrl) {
|
|
1628
|
+
|| latest?.version !== plugin.version || pluginInstallSpec(latest) !== installSpec) {
|
|
1618
1629
|
throw new Error('插件审核信息已变化,请刷新目录后重试。')
|
|
1619
1630
|
}
|
|
1620
1631
|
const requestId = crypto.randomUUID()
|
|
1621
1632
|
let result
|
|
1622
|
-
|
|
1633
|
+
const options = artifactUrl
|
|
1634
|
+
? { enabled: true, requestId }
|
|
1635
|
+
: { enabled: true, requestId, registry: 'https://registry.npmjs.org/' }
|
|
1636
|
+
try { result = await manager.installBundle(installSpec, options) }
|
|
1623
1637
|
catch { result = null }
|
|
1624
1638
|
if (!result?.ok) {
|
|
1625
1639
|
let recovered = null
|
|
@@ -1671,7 +1685,9 @@ window.__ModuleLoader__.load({
|
|
|
1671
1685
|
return
|
|
1672
1686
|
}
|
|
1673
1687
|
await refresh()
|
|
1674
|
-
|
|
1688
|
+
if (artifactUrl && plugin.artifact_sha256) {
|
|
1689
|
+
try { localStorage.setItem(`${PLUGIN_INSTALL_RECORD_PREFIX}${plugin.id}`, plugin.artifact_sha256) } catch {}
|
|
1690
|
+
}
|
|
1675
1691
|
setCompletedId(plugin.id)
|
|
1676
1692
|
setMessage(`${plugin.title} 已安装。请完全退出并重新启动 DSH 后使用。`)
|
|
1677
1693
|
} catch (error) {
|
|
@@ -1682,10 +1698,12 @@ window.__ModuleLoader__.load({
|
|
|
1682
1698
|
const visible = plugins.filter((plugin) => {
|
|
1683
1699
|
const installed = bundles.find((bundle) => bundle.name === plugin.package_name && bundle.installed)
|
|
1684
1700
|
const artifactUrl = approvedPluginArtifactUrl(plugin)
|
|
1701
|
+
const installSpec = pluginInstallSpec(plugin)
|
|
1702
|
+
const localAhead = installed?.version && newerVersion(installed.version, plugin.version)
|
|
1685
1703
|
const matches = !query.trim() || `${plugin.title} ${plugin.description} ${plugin.package_name}`.toLowerCase().includes(query.trim().toLowerCase())
|
|
1686
1704
|
return matches && (activeFilter === 'all' || activeFilter === 'installed' && Boolean(installed)
|
|
1687
|
-
|| activeFilter === 'available' &&
|
|
1688
|
-
|| activeFilter === 'updates' &&
|
|
1705
|
+
|| activeFilter === 'available' && installSpec && !localAhead && (!installed || (installed.version && installed.version !== plugin.version))
|
|
1706
|
+
|| activeFilter === 'updates' && installSpec && installed && installed.version && installed.version !== plugin.version && !localAhead
|
|
1689
1707
|
|| activeFilter === 'retired' && plugin.status !== 'published')
|
|
1690
1708
|
})
|
|
1691
1709
|
const noMatches = embedded
|
|
@@ -1707,7 +1725,7 @@ window.__ModuleLoader__.load({
|
|
|
1707
1725
|
embedded ? null : h('div', { style: { display: 'flex', flexWrap: 'wrap', justifyContent: 'space-between', gap: 16 } },
|
|
1708
1726
|
h('div', null,
|
|
1709
1727
|
h('h1', { style: { margin: 0, fontSize: 28 } }, '企业精选插件'),
|
|
1710
|
-
h('p', { style: { ...mutedTextStyle, marginTop: 6 } }, '这里展示团队审核过的插件版本及本机状态。')),
|
|
1728
|
+
h('p', { style: { ...mutedTextStyle, marginTop: 6 } }, '这里展示团队审核过的插件版本及本机状态。DSH 0.2.0-rc.2 不会自动更新 Bundle;插件自身的更新器可能绕过此目录安装其他版本。')),
|
|
1711
1729
|
h('button', { type: 'button', disabled: loading, onClick: () => void refresh(), style: secondaryButtonStyle }, loading ? '读取中…' : '刷新目录')),
|
|
1712
1730
|
!loading && !plugins.length && !loadError ? embedded
|
|
1713
1731
|
? h('p', { role: 'status', style: mutedTextStyle }, '团队暂未发布精选插件。')
|
|
@@ -1729,16 +1747,19 @@ window.__ModuleLoader__.load({
|
|
|
1729
1747
|
const sameVersion = local?.version === plugin.version
|
|
1730
1748
|
const security = plugin.status === 'security_withdrawn'
|
|
1731
1749
|
const artifactUrl = approvedPluginArtifactUrl(plugin)
|
|
1750
|
+
const installSpec = pluginInstallSpec(plugin)
|
|
1751
|
+
const localAhead = local?.version && newerVersion(local.version, plugin.version)
|
|
1732
1752
|
const sourceKnown = typeof local?.source === 'string'
|
|
1733
1753
|
const verifiedLocal = sameVersion && artifactUrl && sourceKnown && local.source === artifactUrl
|
|
1734
1754
|
const recordedInstall = sameVersion && !sourceKnown && previouslyInstalledReviewedPlugin(plugin)
|
|
1735
1755
|
const status = security ? '已废弃(安全风险)'
|
|
1736
|
-
: plugin.status === 'deprecated' ? '已废弃' : local?.error ? '加载异常' :
|
|
1756
|
+
: plugin.status === 'deprecated' ? '已废弃' : local?.error ? '加载异常' : localAhead
|
|
1757
|
+
? '本机版本高于团队目录版本' : sameVersion
|
|
1737
1758
|
? verifiedLocal ? local.enabled ? '本机已装(团队来源,已启用)' : '本机已装(团队来源,未启用)'
|
|
1738
1759
|
: sourceKnown ? '本机同版,来源不同' : recordedInstall
|
|
1739
1760
|
? '本机同版,曾由企业扩展安装;当前 DSH 无法复核来源' : '本机同版,当前 DSH 无法核对来源'
|
|
1740
|
-
:
|
|
1741
|
-
: local ? `本机版本 ${local.version || '暂无法读取'}` : '
|
|
1761
|
+
: installSpec ? local ? local.version ? `可更新 · 本机 ${local.version}` : '本机版本暂无法读取' : artifactUrl ? '可安装' : '可从 npm 安装'
|
|
1762
|
+
: local ? `本机版本 ${local.version || '暂无法读取'}` : '已发布版本暂不可安装'
|
|
1742
1763
|
return h('article', { key: plugin.id, style: security
|
|
1743
1764
|
? { ...panelStyle, borderColor: 'var(--dsw-alias-label-danger, #d44)' } : panelStyle },
|
|
1744
1765
|
h('div', { style: { display: 'flex', flexWrap: 'wrap', justifyContent: 'space-between', gap: 8 } },
|
|
@@ -1751,6 +1772,10 @@ window.__ModuleLoader__.load({
|
|
|
1751
1772
|
h('p', { style: mutedTextStyle }, `${plugin.package_name}@${plugin.version} · 许可证:${plugin.license || '未声明'}`),
|
|
1752
1773
|
h('p', { style: mutedTextStyle }, `来源:${plugin.source_url || '未提供'} · DSH 版本要求:${plugin.peer_range || '包未声明'}`),
|
|
1753
1774
|
h('p', { style: mutedTextStyle }, `额外配置:${plugin.requirements || '无'}`),
|
|
1775
|
+
installSpec && !artifactUrl ? h('p', { role: 'note', style: mutedTextStyle },
|
|
1776
|
+
'ANT 通过 DSH 包管理器安装目录中的精确 npm 版本;实际下载和依赖解析由 DSH 执行。ANT 不批准依赖构建脚本;若 DSH 因此拒绝安装,请按 DSH 提示在原生插件管理页处理。插件自身更新器或 DSH 原生管理也可更新到目录外的版本。') : null,
|
|
1777
|
+
plugin.dependencies && artifactUrl ? h('p', { role: 'note', style: mutedTextStyle },
|
|
1778
|
+
'此插件声明了依赖。ANT 固定插件包本身;DSH 会在本机按当前配置解析依赖,不同设备可能得到不同版本。依赖构建脚本由 DSH 单独请求批准。') : null,
|
|
1754
1779
|
plugin.scripts ? h('p', { style: mutedTextStyle }, `包自身的安装脚本:${plugin.scripts}`) : null,
|
|
1755
1780
|
plugin.status !== 'published' ? h('p', { role: 'status', style: security
|
|
1756
1781
|
? { ...mutedTextStyle, color: 'var(--dsw-alias-label-danger, #d44)' } : mutedTextStyle },
|
|
@@ -1760,16 +1785,17 @@ window.__ModuleLoader__.load({
|
|
|
1760
1785
|
? '此前曾由企业扩展安装;当前 DSH 无法再次核对来源。正常使用无需重复安装;若后来换过来源,可以重新安装。'
|
|
1761
1786
|
: '已装同版且使用正常时无需重复安装;若想改用团队审核包,可自愿安装。') : null,
|
|
1762
1787
|
h('div', { style: { display: 'flex', flexWrap: 'wrap', gap: 8 } },
|
|
1763
|
-
|
|
1788
|
+
installSpec && (!local || (local.version && local.version !== plugin.version && (!localAhead || artifactUrl))
|
|
1789
|
+
|| (artifactUrl && sameVersion && !verifiedLocal))
|
|
1764
1790
|
? h('button', { type: 'button', disabled: Boolean(workingId) || uncertainId === plugin.id || completedId === plugin.id,
|
|
1765
1791
|
onClick: () => void install(plugin), style: primaryButtonStyle },
|
|
1766
1792
|
workingId === plugin.id ? '安装中…' : uncertainId === plugin.id ? '先核对安装结果'
|
|
1767
1793
|
: completedId === plugin.id ? '重启 DSH 后生效'
|
|
1768
|
-
: local ? sameVersion ? '按团队审核包重新安装' : '更新到审核版本' : '安装到这台 DSH') : null,
|
|
1769
|
-
plugin.status === 'published' && !local && !
|
|
1794
|
+
: local ? sameVersion || localAhead ? '按团队审核包重新安装' : '更新到审核版本' : '安装到这台 DSH') : null,
|
|
1795
|
+
plugin.status === 'published' && !local && !installSpec
|
|
1770
1796
|
? h('p', { style: mutedTextStyle }, '如需安装,请联系企业管理员安排。') : null,
|
|
1771
1797
|
local || uncertainId === plugin.id ? h('button', { type: 'button', onClick: () => openBundle(plugin.package_name), style: secondaryButtonStyle }, '打开 DSH 插件管理') : null,
|
|
1772
|
-
local && !sameVersion && plugin.status === 'published' && !
|
|
1798
|
+
local && !sameVersion && plugin.status === 'published' && !installSpec
|
|
1773
1799
|
? h('p', { style: mutedTextStyle }, '本机版本与团队审核版本不同;请联系企业管理员核对。') : null))
|
|
1774
1800
|
})) : !loading && plugins.length && (!embedded || !hasSkillMatches)
|
|
1775
1801
|
? h('p', { style: mutedTextStyle }, noMatches) : null))
|