prts-terrarchive 0.2.2 → 0.2.4

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.
Files changed (40) hide show
  1. package/README.en.md +52 -18
  2. package/README.md +49 -16
  3. package/bin/build-mainline-catalog.py +195 -0
  4. package/contracts/corpus_i18n_v1.schema.json +1 -3
  5. package/contracts/corpus_tools_v1.schema.json +30 -1
  6. package/docs/endfield-mainline-navigation.md +45 -0
  7. package/lib/client.js +154 -27
  8. package/lib/skins/common.css +12 -2
  9. package/lib/skins/endfield-aic.css +1 -1
  10. package/lib/skins/prts-agent.css +9 -7
  11. package/package.json +7 -3
  12. package/resources/endfield-mainline.json +4632 -0
  13. package/skills/prts-investigation/SKILL.md +1 -1
  14. package/skills/prts-investigation/references/board-guide.md +1 -1
  15. package/skills/prts-retrieval/SKILL.md +2 -0
  16. package/skills/prts-retrieval/references/cloud-tools.md +3 -1
  17. package/skills/prts-retrieval/references/local-tools.md +3 -3
  18. package/skills/prts-retrieval/references/module-arknights.md +1 -1
  19. package/skills/prts-retrieval/references/module-dual.md +1 -1
  20. package/skills/prts-retrieval/references/module-endfield.md +3 -0
  21. package/skills/prts-retrieval/references/tools-runtime.md +22 -10
  22. package/src/cloud-projection.js +23 -2
  23. package/src/cloud.js +24 -0
  24. package/src/entity-recognizer.js +26 -5
  25. package/src/entity-routing.js +18 -4
  26. package/src/evidence-state.js +4 -2
  27. package/src/i18n.js +70 -15
  28. package/src/index.js +326 -103
  29. package/src/installer.js +86 -14
  30. package/src/investigation-tools.js +7 -4
  31. package/src/navigation.js +342 -0
  32. package/src/read-args.js +86 -0
  33. package/src/read.js +66 -15
  34. package/src/search-projection.js +154 -19
  35. package/src/search.js +177 -21
  36. package/src/store.js +127 -3
  37. package/src/timeline.js +86 -2
  38. package/src/tool-args.js +53 -0
  39. package/src/ui.js +158 -34
  40. package/src/web-guidance.js +14 -2
package/lib/client.js CHANGED
@@ -810,7 +810,13 @@ window.__ModuleLoader__.load({
810
810
  if (conversationRect?.width > 0) {
811
811
  const shellOverlay = document.querySelector('[data-shell-overlay]')
812
812
  const shell = shellOverlay?.parentElement
813
- const sidebarRect = shell?.querySelector(':scope > div:nth-of-type(1)')?.getBoundingClientRect?.()
813
+ // 侧栏列没有自己的稳定属性,只有 display:contents 的
814
+ // [data-slot="sidebar"] 锚点。优先用"包含该锚点的那一列"定位,
815
+ // nth-of-type 只在老版式下兜底:DSH 0.2.1 的 frame 里新增了
816
+ // shell.bottom 等兄弟节点,靠序号会逐渐不可靠。
817
+ const sidebarColumn = shell?.querySelector(':scope > div:has(> [data-slot="sidebar"])')
818
+ ?? shell?.querySelector(':scope > div:nth-of-type(1)')
819
+ const sidebarRect = sidebarColumn?.getBoundingClientRect?.()
814
820
  const contentLeft = Math.max(conversationRect.left, sidebarRect?.right ?? 0)
815
821
  const contentRightEdge = conversationRect.right
816
822
  const contentCenter = contentLeft + (contentRightEdge - contentLeft) / 2
@@ -1940,15 +1946,91 @@ window.__ModuleLoader__.load({
1940
1946
  message || (saving ? '正在应用…' : '选择后立即生效,并保留当前的明亮 / 暗色偏好。')))
1941
1947
  }
1942
1948
 
1949
+ /* ---- 版本管理:本地占用、保留策略、切换/回滚/删除 ---- */
1950
+ const KEEP_RELEASES_LABEL = 3
1951
+
1952
+ function VersionManagerCard({ releases, activeRelease, previousReleaseId,
1953
+ onActivate, onDelete, downloading, onRefresh }) {
1954
+ const [pruning, setPruning] = useState(false)
1955
+ const [message, setMessage] = useState(null)
1956
+ const rows = [...(releases ?? [])].sort((left, right) =>
1957
+ String(right.createdAt ?? '').localeCompare(String(left.createdAt ?? '')))
1958
+ const totalBytes = rows.reduce((sum, item) => sum + (Number(item.compressedSize) || 0), 0)
1959
+ const activeId = activeRelease?.releaseId ?? rows.find((item) => item.active)?.releaseId ?? null
1960
+ const prune = async () => {
1961
+ setPruning(true)
1962
+ setMessage(null)
1963
+ try {
1964
+ const result = await jsonFetch('/prune', { method: 'POST', body: '{}' })
1965
+ const removed = Array.isArray(result?.removed) ? result.removed : []
1966
+ setMessage(removed.length
1967
+ ? `已清理 ${removed.length} 个旧版本`
1968
+ : '没有可清理的版本')
1969
+ onRefresh?.()
1970
+ } catch (error) {
1971
+ setMessage(error.message)
1972
+ } finally {
1973
+ setPruning(false)
1974
+ }
1975
+ }
1976
+ return h('div', { style: S.card },
1977
+ h('div', { style: { ...S.row, justifyContent: 'space-between' } },
1978
+ h('div', null,
1979
+ h('h3', { style: { ...S.cardTitle, marginBottom: '3px' } }, '版本管理'),
1980
+ h('span', { style: S.hint },
1981
+ `本地 ${rows.length} 个版本 · 合计 ${fmtBytes(totalBytes)} · 自动保留最近 ${KEEP_RELEASES_LABEL} 个(当前 + 回滚目标 + 余量)`)),
1982
+ h('div', { style: S.row },
1983
+ h('button', { style: S.button, disabled: pruning || downloading, onClick: prune },
1984
+ pruning ? '清理中…' : '清理旧版本'),
1985
+ h('button', { style: S.button, onClick: () => onRefresh?.() }, '刷新'))),
1986
+ message && h('span', { style: { ...S.hint, display: 'block', marginTop: '6px' } }, message),
1987
+ rows.length === 0 && h('span', { style: { ...S.hint, display: 'block', marginTop: '8px' } },
1988
+ '本地还没有可用于回滚的历史版本。'),
1989
+ rows.length > 0 && h('div', { style: { marginTop: '8px' } }, ...rows.map((release) => {
1990
+ const isActive = release.releaseId === activeId
1991
+ const isPrevious = release.releaseId === previousReleaseId
1992
+ return h('div', { key: release.releaseId, style: S.versionRow },
1993
+ h('div', { style: { minWidth: 0, flex: 1 } },
1994
+ h('strong', { style: { display: 'block', fontFamily: 'ui-monospace, monospace',
1995
+ fontSize: '12px', overflow: 'hidden', textOverflow: 'ellipsis' } },
1996
+ release.releaseId),
1997
+ h('span', { style: S.hint },
1998
+ `${release.createdAt ? fmtDate(release.createdAt) : '—'}`
1999
+ + ` · ${(release.documentCount ?? 0).toLocaleString()} 篇`
2000
+ + ` · ${fmtBytes(release.compressedSize ?? 0)}`
2001
+ + (release.complete === false ? ' · 目录不完整' : ''))),
2002
+ isActive && h('span', { style: S.badgeGreen }, '当前'),
2003
+ isPrevious && !isActive && h('span', { style: S.badgeGray }, '上一版本'),
2004
+ !isActive && h('button', { style: S.button, disabled: !release.complete,
2005
+ onClick: () => onActivate?.(release.releaseId) },
2006
+ isPrevious ? '回滚' : '切换'),
2007
+ !isActive && h('button', { style: S.button, onClick: () => onDelete?.(release.releaseId) },
2008
+ '删除'))
2009
+ })))
2010
+ }
2011
+
1943
2012
  /* ---- 资料库选择与按游戏展开的版本管理 ---- */
1944
- function DatasetLibraryCard({ status, releases, activeRelease, enabledGames, savingGames,
2013
+ function DatasetLibraryCard({ status, releases, activeRelease, previousReleaseId, enabledGames, savingGames,
1945
2014
  onEnabledGames, onRefresh, onCheckUpdate, checking, updateInfo,
1946
2015
  onActivate, onDelete, onDownload, downloading }) {
1947
2016
  const store = status?.store ?? {}
1948
2017
  const download = status?.download ?? {}
2018
+ // 两个按钮分工:检查更新只查询;下载最新只在「没装」或「已确认有新版」时可用,
2019
+ // 避免两个入口都能触发同一次下载。
2020
+ const downloadAllowed = store.installed === false || updateInfo?.kind === 'update'
1949
2021
  const percent = download.filesTotal
1950
2022
  ? Math.round((download.filesDone / download.filesTotal) * 100) : null
1951
2023
  const [expandedGame, setExpandedGame] = useState(null)
2024
+ // 下载完成后不要一直把进度条钉在设置页(issue #5):done 只保留几秒,
2025
+ // 之后收起;失败状态不自动收起,避免把错误藏起来。
2026
+ const [doneDismissed, setDoneDismissed] = useState(false)
2027
+ const downloadSettled = download.phase === 'done' && !download.active
2028
+ useEffect(() => {
2029
+ setDoneDismissed(false)
2030
+ if (!downloadSettled) return undefined
2031
+ const timer = setTimeout(() => setDoneDismissed(true), 8000)
2032
+ return () => clearTimeout(timer)
2033
+ }, [downloadSettled, download.finishedAt, download.releaseId, download.error])
1952
2034
  const games = [
1953
2035
  { id: 'arknights', title: '明日方舟', subtitle: '剧情、档案、Wiki 与实体资料' },
1954
2036
  { id: 'endfield', title: '明日方舟:终末地', subtitle: '剧情原文、档案库与自建 Wiki' },
@@ -1970,7 +2052,13 @@ window.__ModuleLoader__.load({
1970
2052
  const releaseName = dataset?.releaseTitle
1971
2053
  || knownTitles[dataset?.releaseName] || dataset?.releaseName
1972
2054
  const names = [releaseName, dataset?.gameVersion].filter(Boolean)
1973
- return names.length ? names.join(' · ') : release.releaseId
2055
+ if (names.length) return names.join(' · ')
2056
+ // 明日方舟侧的资料包没有人类可读版本名时,不要把整条 release id 甩给用户;
2057
+ // 优先展示安装日期与数据版本,让人一眼知道「装的是哪一份」。
2058
+ const when = release?.createdAt ? fmtDate(release.createdAt).slice(0, 10) : ''
2059
+ const data = dataset?.dataVersion ? `数据 ${shortVersion(dataset.dataVersion)}` : ''
2060
+ const fallback = [when, data].filter(Boolean).join(' · ')
2061
+ return fallback || release.releaseId
1974
2062
  }
1975
2063
  const versionRows = expandedGame == null ? [] : (releases ?? [])
1976
2064
  .filter((release) => release.datasets?.[expandedGame]?.present)
@@ -1983,8 +2071,14 @@ window.__ModuleLoader__.load({
1983
2071
  h('button', { style: S.button, onClick: onRefresh }, '刷新'),
1984
2072
  h('button', { style: S.button, disabled: checking, onClick: onCheckUpdate },
1985
2073
  checking ? '检查中…' : '检查更新'),
1986
- h('button', { style: S.buttonPrimary, disabled: downloading, onClick: () => onDownload() },
2074
+ h('button', { style: S.buttonPrimary, onClick: () => onDownload(),
2075
+ disabled: downloading || checking || !downloadAllowed,
2076
+ title: downloadAllowed ? '' : '已是最新;先点「检查更新」确认远端是否有新版本' },
1987
2077
  downloading ? '下载中…' : '下载最新'))),
2078
+ h('span', { style: { ...S.hint, display: 'block', marginTop: '6px' } },
2079
+ downloadAllowed
2080
+ ? '检查更新只比对 PRTS.chat 的发布版本,不改本地文件;下载最新会安装该版本。'
2081
+ : '本地已是最新版本;「检查更新」用来确认远端,有新版后这里才能下载。'),
1988
2082
  store.installed === false && h('div', { style: { ...S.error, marginTop: '8px' } },
1989
2083
  `本地资料尚未就绪:${store.installationIssue || '未找到有效版本'}。便携版用户还应确认 ZIP 已完整解压。`),
1990
2084
  store.installed === true && !store.loaded && h('div', { style: { ...S.hint, marginTop: '8px' } },
@@ -2023,16 +2117,21 @@ window.__ModuleLoader__.load({
2023
2117
  updateInfo?.text && h('div', { style: { ...S.row, marginTop: '8px' } },
2024
2118
  h('span', { style: updateInfo.kind === 'error' ? S.error : updateInfo.kind === 'update' ? S.badgeGreen : S.badgeGray },
2025
2119
  updateInfo.text),
2026
- updateInfo.kind === 'update' && updateInfo.remoteReleaseId
2027
- && h('button', { style: S.buttonPrimary, onClick: updateInfo.onDownload }, '下载更新')),
2028
- download.phase && download.phase !== 'idle'
2120
+ // 下载入口统一收到右上角「下载最新」,这里只报状态。
2121
+ ),
2122
+ download.phase && download.phase !== 'idle' && !(downloadSettled && doneDismissed)
2029
2123
  ? h('div', { style: { ...S.row, marginTop: '8px' } },
2030
- h('span', { style: S.key }, download.active ? '下载中' : '下载状态'),
2031
- h('span', { style: S.badge }, `${download.source ?? ''} · ${download.phase}`),
2032
- percent !== null && h('div', { style: S.progressTrack },
2124
+ h('span', { style: S.key }, downloadSettled ? '下载结果' : '下载中'),
2125
+ h('span', { style: downloadSettled ? S.badgeGreen : S.badge },
2126
+ downloadSettled
2127
+ ? `已完成${download.source ? ` · ${download.source}` : ''}`
2128
+ : `${download.source ?? ''} · ${download.phase}`),
2129
+ // 只有进行中的下载才画宽进度条;完成后用一行摘要代替。
2130
+ !downloadSettled && percent !== null && h('div', { style: S.progressTrack },
2033
2131
  h('div', { style: { ...S.progressFill, width: `${percent}%` } })),
2034
2132
  h('span', { style: S.hint },
2035
- `${download.filesDone}/${download.filesTotal ?? '?'} 文件 · ${fmtBytes(download.bytesDone)}`),
2133
+ `${download.filesDone}/${download.filesTotal ?? '?'} 文件 · ${fmtBytes(download.bytesDone)}`
2134
+ + (downloadSettled && download.finishedAt ? ` · ${fmtDate(download.finishedAt)}` : '')),
2036
2135
  download.error && h('span', { style: S.error }, download.error))
2037
2136
  : null,
2038
2137
  expandedGame && h('div', { style: S.versionPanel },
@@ -2051,8 +2150,11 @@ window.__ModuleLoader__.load({
2051
2150
  release.active
2052
2151
  ? h('span', { style: S.badgeGreen }, '当前')
2053
2152
  : h(Fragment, null,
2153
+ release.releaseId === previousReleaseId
2154
+ && h('span', { style: S.badgeGray }, '上一版本'),
2054
2155
  h('button', { style: S.button, disabled: !release.complete,
2055
- onClick: () => onActivate(release.releaseId) }, '切换'),
2156
+ onClick: () => onActivate(release.releaseId) },
2157
+ release.releaseId === previousReleaseId ? '回滚' : '切换'),
2056
2158
  h('button', { style: S.button, onClick: () => onDelete(release.releaseId) }, '删除')))
2057
2159
  }),
2058
2160
  versionRows.length === 0 && h('span', { style: S.hint }, '本地没有这个资料库的版本。')),
@@ -2061,16 +2163,21 @@ window.__ModuleLoader__.load({
2061
2163
  }
2062
2164
 
2063
2165
  /* ---- 配置编辑 ---- */
2166
+ const MIB = 1024 * 1024
2167
+ // 第三项是展示单位换算:存储仍是字节,界面按 MB 给,避免让用户填 33554432。
2064
2168
  const NUMBER_FIELDS = [
2065
2169
  ['cacheShards', '分片缓存数'],
2066
2170
  ['cloudTimeoutMs', '云端超时(ms)'],
2067
- ['cloudMaxResponseBytes', '云端响应上限(B)'],
2171
+ ['cloudMaxResponseBytes', '云端响应上限(MB)', MIB],
2068
2172
  ]
2069
2173
 
2070
2174
  function ConfigCard({ config, onSaved }) {
2071
2175
  const [draft, setDraft] = useState(null)
2072
2176
  const [saving, setSaving] = useState(false)
2073
2177
  const [message, setMessage] = useState(null)
2178
+ // 云端/资料站点地址默认都是 https://prts.chat,绝大多数用户不用改;
2179
+ // 收进「高级」里,避免两个同值 URL 并排让人误以为要填两处。
2180
+ const [showAdvanced, setShowAdvanced] = useState(false)
2074
2181
  if (!config) return null
2075
2182
  const value = draft ?? {}
2076
2183
  const current = (key, fallback) => Object.hasOwn(value, key) ? value[key] : (config[key] ?? fallback)
@@ -2099,25 +2206,38 @@ window.__ModuleLoader__.load({
2099
2206
  h('input', { type: 'checkbox', checked: Boolean(current('cloudEnabled', false)),
2100
2207
  onChange: set('cloudEnabled') }),
2101
2208
  h('span', { style: S.hint }, 'cloud_search / cloud_inspect(保存后即时注册/注销)')),
2102
- h('div', { style: S.field },
2103
- h('span', { style: S.fieldKey }, '云端检索地址'),
2104
- h('input', { style: S.input, value: String(current('cloudBaseUrl', '')),
2105
- onChange: set('cloudBaseUrl') }),
2106
- h('span', { style: { ...S.hint, flexBasis: '100%', marginLeft: '148px' } }, 'cloud_search / cloud_inspect 服务')),
2107
2209
  h('div', { style: S.field },
2108
2210
  h('span', { style: S.fieldKey }, '访问令牌'),
2109
2211
  h('input', { style: S.input, type: 'password',
2110
2212
  placeholder: config.hasCloudToken ? '已设置(不修改即保持)' : '留空使用匿名会话',
2111
2213
  value: String(current('cloudToken', '')), onChange: set('cloudToken') })),
2112
2214
  h('div', { style: S.grid2 },
2113
- ...NUMBER_FIELDS.map(([key, label]) => h('div', { key, style: S.field },
2215
+ ...NUMBER_FIELDS.map(([key, label, scale]) => h('div', { key, style: S.field },
2114
2216
  h('span', { style: S.fieldKey }, label),
2115
2217
  h('input', { style: { ...S.input, flex: '0 0 96px', width: '96px' }, type: 'number',
2116
- value: String(current(key, '')), onChange: set(key, Number) })))),
2218
+ value: String(scale
2219
+ ? Math.round(((Number(current(key, 0)) || 0) / scale) * 100) / 100
2220
+ : current(key, '')),
2221
+ onChange: set(key, (raw) => (scale ? Math.round(Number(raw) * scale) : Number(raw))) })))),
2117
2222
  h('div', { style: S.field },
2118
- h('span', { style: S.fieldKey }, '资料站点地址'),
2119
- h('input', { style: S.input, value: String(current('downloadSiteBaseUrl', '')),
2120
- onChange: set('downloadSiteBaseUrl') })),
2223
+ h('span', { style: S.fieldKey }, '高级'),
2224
+ h('button', { style: S.buttonLink,
2225
+ onClick: () => setShowAdvanced((previous) => !previous) },
2226
+ showAdvanced ? '收起地址设置' : '显示地址设置'),
2227
+ h('span', { style: S.hint }, '云端与资料站点默认都是 https://prts.chat,一般不需要改。')),
2228
+ showAdvanced && h(Fragment, null,
2229
+ h('div', { style: S.field },
2230
+ h('span', { style: S.fieldKey }, '云端检索地址'),
2231
+ h('input', { style: S.input, value: String(current('cloudBaseUrl', '')),
2232
+ onChange: set('cloudBaseUrl') }),
2233
+ h('span', { style: { ...S.hint, flexBasis: '100%', marginLeft: '148px' } },
2234
+ 'cloud_search / cloud_inspect 使用的服务地址')),
2235
+ h('div', { style: S.field },
2236
+ h('span', { style: S.fieldKey }, '资料站点地址'),
2237
+ h('input', { style: S.input, value: String(current('downloadSiteBaseUrl', '')),
2238
+ onChange: set('downloadSiteBaseUrl') }),
2239
+ h('span', { style: { ...S.hint, flexBasis: '100%', marginLeft: '148px' } },
2240
+ '下载资料包时先按 PRTS.chat current 校验版本,再按镜像顺序取文件'))),
2121
2241
  h('div', { style: S.field },
2122
2242
  h('span', { style: S.fieldKey }, '下载源顺序'),
2123
2243
  h('select', { style: S.select, value: current('downloadOrder', ['modelscope', 'site']).join(','),
@@ -2326,13 +2446,17 @@ window.__ModuleLoader__.load({
2326
2446
  return h('div', { style: S.wrap, className: 'prts-settings-wrap' },
2327
2447
  error && h('div', { style: { ...S.card, ...S.error } }, error),
2328
2448
  h(SkinCard, { skin, onChanged: onSkinChanged }),
2329
- h(DatasetLibraryCard, { status, activeRelease,
2449
+ h(DatasetLibraryCard, { status, activeRelease, previousReleaseId: releaseList?.previousId ?? null,
2330
2450
  releases: releaseList?.releases ?? [], enabledGames, savingGames,
2331
2451
  onEnabledGames: updateEnabledGames, onRefresh: refresh,
2332
2452
  onCheckUpdate: checkUpdate, checking, updateInfo: statusUpdateInfo,
2333
2453
  onActivate: activate, onDelete: remove, onDownload: download,
2334
2454
  downloading: busy || Boolean(status?.download?.active),
2335
2455
  }),
2456
+ h(VersionManagerCard, { releases: releaseList?.releases ?? [], activeRelease,
2457
+ previousReleaseId: releaseList?.previousId ?? null,
2458
+ onActivate: activate, onDelete: remove, onRefresh: refresh,
2459
+ downloading: busy || Boolean(status?.download?.active) }),
2336
2460
  h(ConfigCard, { config: status?.config, onSaved: refresh }))
2337
2461
  }
2338
2462
 
@@ -2787,7 +2911,9 @@ window.__ModuleLoader__.load({
2787
2911
  || !Array.isArray(root.content)) return null
2788
2912
  // PTC receipts are their own log-only block, never text to parse or show.
2789
2913
  // Bind all three identities before accepting a durable source projection.
2790
- const receipt = root.content.find((block) => block?.type === 'prts-archive-receipt'
2914
+ // DSH 的 v3→v4 会话迁移会给未知 block 加 `plugin:` 前缀,两种拼写都要认。
2915
+ const receiptType = (type) => type === 'prts-archive-receipt' || type === 'plugin:prts-archive-receipt'
2916
+ const receipt = root.content.find((block) => receiptType(block?.type)
2791
2917
  && block.version === 1 && block.callId === root.callId
2792
2918
  && block.parentCallId === root.parentCallId && block.tool === root.call?.name
2793
2919
  && supported(block.meta) && Array.isArray(block.meta.sources)
@@ -3847,9 +3973,10 @@ window.__ModuleLoader__.load({
3847
3973
  /* ---- 插件入口:Settings → Plugins 的「PRTS 语料」tab ---- */
3848
3974
  exports.__sceneStateForTest = { buildSceneSnapshotModel, sceneSnapshotSignature,
3849
3975
  collectSnapshotEvidence, buildEvidence, readEvidenceSource, installDialogFocusTrap }
3850
- exports.__rhineStateForTest = { buildRhineSnapshot, mergeArchiveSources, rhineSnapshotSignature, submitRhineQuestion, RhineControl, createRhineHostControls, createRhineSnapshotDiagnostics, createRhineSnapshotSelector }
3976
+ exports.__rhineStateForTest = { buildRhineSnapshot, mergeArchiveSources, rhineSnapshotSignature, submitRhineQuestion, rhineToolPresentation, RhineControl, createRhineHostControls, createRhineSnapshotDiagnostics, createRhineSnapshotSelector }
3851
3977
  exports.__skinStateForTest = {
3852
- setSkin, writeSkinConfig, SkinCard, PrtsSection, openHostSettings, isHostSettingsOpen,
3978
+ setSkin, writeSkinConfig, SkinCard, PrtsSection, VersionManagerCard, DatasetLibraryCard,
3979
+ openHostSettings, isHostSettingsOpen,
3853
3980
  finishAicBoot: () => aicBootDone(),
3854
3981
  getActiveSkin: () => activeSkin,
3855
3982
  getHostSkinSyncGeneration: () => hostSkinSyncGeneration,
@@ -50,16 +50,26 @@ body[data-prts-skin] [data-plugin-panel]>header>div:first-child::before {
50
50
  letter-spacing:.12em;
51
51
  }
52
52
  body[data-prts-skin] [data-plugin-group]>ul {gap:8px}
53
- body[data-prts-skin] :is([data-plugin-package],[data-plugin-item]) {
53
+ body[data-prts-skin] :is([data-plugin-package],[data-plugin-item],[data-plugin-entry]) {
54
54
  margin:0;
55
55
  padding:5px;
56
56
  border:1px solid var(--prts-plugins-rule);
57
57
  border-radius:var(--prts-plugins-radius);
58
58
  background:var(--prts-plugins-card);
59
59
  }
60
- body[data-prts-skin] :is([data-plugin-package],[data-plugin-item]):is(:hover,:focus-within) {
60
+ body[data-prts-skin] :is([data-plugin-package],[data-plugin-item],[data-plugin-entry]):is(:hover,:focus-within) {
61
61
  border-color:var(--prts-plugins-accent);
62
62
  }
63
+ /* DSH 0.2.1 moved the per-entry plugin inventory into a Settings tab. It names
64
+ its entries with data-plugin-entry/module/scope instead of the page cards,
65
+ so the same card treatment is applied there through those attributes. */
66
+ body[data-prts-skin] [data-slot="settings.section"] [data-plugin-scope] {
67
+ border-top:1px solid var(--prts-plugins-rule);
68
+ padding-top:14px;
69
+ }
70
+ body[data-prts-skin] [data-slot="settings.section"] [data-plugin-scope] [data-plugin-entry] code {
71
+ font-family:ui-monospace,monospace;
72
+ }
63
73
  body[data-prts-skin] :is([data-plugin-config],[data-plugin-rows]) {
64
74
  box-sizing:border-box;
65
75
  padding:20px;
@@ -12,7 +12,7 @@ body.aic-chat-resizing,body.aic-chat-resizing *{cursor:col-resize!important;user
12
12
  body[data-prts-skin="endfield-aic"] [data-sidebar-right-panel]{z-index:55}
13
13
  body[data-prts-skin="endfield-aic"] [data-side="rightbar"]{z-index:56}
14
14
  body[data-prts-skin="endfield-aic"]:has(.aic-drawer) :is([data-sidebar-right-panel],[data-side="rightbar"]){z-index:30}
15
- body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) #root>[data-slot="root"]>div{grid-template-columns:0 minmax(0,1fr) 0!important;background:#14181b}body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) #root>[data-slot="root"]>div>div:first-child{visibility:visible;width:0!important;overflow:visible!important;pointer-events:none}body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])).aic-modal-open #root>[data-slot="root"]>div>div:first-child{position:relative;z-index:100!important}body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) #root>[data-slot="root"]>div>div:first-child [data-slot="sidebar.settings"] button[aria-haspopup="dialog"]{display:none!important}body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) #root>[data-slot="root"]>div>div:first-child [data-slot="sidebar.settings"]>[role="presentation"]{visibility:visible;pointer-events:auto}body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) [data-shell-overlay="true"]{z-index:40!important}body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) :is([data-slot="conversation"],[data-slot="main.conversation"])>div{position:fixed!important;z-index:50;top:104px;bottom:0;left:0;width:var(--prts-aic-band-width,min(clamp(760px,46vw,960px),calc(100vw - 360px)));height:calc(100vh - 104px)!important;min-height:0;overflow:visible!important;background:transparent!important;box-shadow:none;pointer-events:none}body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) :is([data-slot="conversation"],[data-slot="main.conversation"])>div::before{content:none!important}body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) :is([data-slot="conversation"],[data-slot="main.conversation"]) :is([data-conversation-scroll],[data-composer-seat],button,textarea,select,details,[contenteditable="true"]){pointer-events:auto}body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) :is([data-slot="conversation"],[data-slot="main.conversation"]) button,body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) :is([data-slot="conversation"],[data-slot="main.conversation"]) textarea,body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) :is([data-slot="conversation"],[data-slot="main.conversation"]) select{border-radius:0!important}body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) :is([data-slot="conversation"],[data-slot="main.conversation"]) details,body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) :is([data-slot="conversation"],[data-slot="main.conversation"]) pre{border-radius:0!important}body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) [data-slot="conversation.composer.bar"]>div{border-color:rgba(255,255,255,.18)!important;background:rgba(10,13,15,.96)!important;box-shadow:none!important}body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) [data-slot="conversation.input.model"] button,body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) [data-slot="conversation.input.plan"] button,body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) [data-slot="conversation.hero.workspace"] button{color:rgba(238,240,235,.78)!important;background:transparent!important}body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) [data-slot="shell.overlay"]{position:fixed;z-index:40;inset:0;pointer-events:none}
15
+ body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) #root>[data-slot="root"]>div{grid-template-columns:0 minmax(0,1fr) 0!important;background:#14181b}body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) #root>[data-slot="root"]>div>div:has(> [data-slot="sidebar"]){visibility:visible;width:0!important;overflow:visible!important;pointer-events:none}body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])).aic-modal-open #root>[data-slot="root"]>div>div:has(> [data-slot="sidebar"]){position:relative;z-index:100!important}body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) #root>[data-slot="root"]>div>div:has(> [data-slot="sidebar"]) [data-slot="sidebar.settings"] button[aria-haspopup="dialog"]{display:none!important}body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) #root>[data-slot="root"]>div>div:has(> [data-slot="sidebar"]) [data-slot="sidebar.settings"]>[role="presentation"]{visibility:visible;pointer-events:auto}body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) [data-shell-overlay]{z-index:40!important}body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) :is([data-slot="conversation"],[data-slot="main.conversation"])>div{position:fixed!important;z-index:50;top:104px;bottom:0;left:0;width:var(--prts-aic-band-width,min(clamp(760px,46vw,960px),calc(100vw - 360px)));height:calc(100vh - 104px)!important;min-height:0;overflow:visible!important;background:transparent!important;box-shadow:none;pointer-events:none}body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) :is([data-slot="conversation"],[data-slot="main.conversation"])>div::before{content:none!important}body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) :is([data-slot="conversation"],[data-slot="main.conversation"]) :is([data-conversation-scroll],[data-composer-seat],button,textarea,select,details,[contenteditable="true"]){pointer-events:auto}body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) :is([data-slot="conversation"],[data-slot="main.conversation"]) button,body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) :is([data-slot="conversation"],[data-slot="main.conversation"]) textarea,body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) :is([data-slot="conversation"],[data-slot="main.conversation"]) select{border-radius:0!important}body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) :is([data-slot="conversation"],[data-slot="main.conversation"]) details,body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) :is([data-slot="conversation"],[data-slot="main.conversation"]) pre{border-radius:0!important}body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) [data-slot="conversation.composer.bar"]>div{border-color:rgba(255,255,255,.18)!important;background:rgba(10,13,15,.96)!important;box-shadow:none!important}body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) [data-slot="conversation.input.model"] button,body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) [data-slot="conversation.input.plan"] button,body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) [data-slot="conversation.hero.workspace"] button{color:rgba(238,240,235,.78)!important;background:transparent!important}body[data-prts-skin="endfield-aic"]:not(:has([data-plugin-panel])) [data-slot="shell.overlay"]{position:fixed;z-index:40;inset:0;pointer-events:none}
16
16
  .aic-map-reset{position:absolute;z-index:8;top:22px;right:286px;height:26px;padding:0 12px;border:1px solid rgba(255,255,255,.18);border-radius:0;color:rgba(244,245,241,.7);background:rgba(7,9,10,.52);font:9px ui-monospace,monospace;cursor:pointer;pointer-events:auto}.aic-map-reset:hover{border-color:var(--acid);color:var(--acid)}
17
17
  .aic-region-card{position:absolute;z-index:9;right:24px;top:92px;width:300px;padding:16px;border:1px solid rgba(250,255,63,.28);border-left:3px solid var(--acid);color:#e8eae5;background:rgba(7,9,10,.9);box-shadow:0 18px 45px rgba(0,0,0,.32);backdrop-filter:blur(10px)}.aic-region-card small{color:var(--acid);font:8px ui-monospace,monospace;letter-spacing:.1em}.aic-region-card h3{margin:12px 0 1px;font-size:20px}.aic-region-card em{color:rgba(238,240,235,.35);font:9px ui-monospace,monospace}.aic-region-card p{margin:14px 0;color:rgba(238,240,235,.7);font-size:12px;line-height:1.7}.aic-region-card b{color:rgba(238,240,235,.38);font:8px ui-monospace,monospace}
18
18
  .aic-hud{position:absolute;z-index:30;font:10px/1.35 ui-monospace,monospace;letter-spacing:.08em;text-shadow:0 1px 4px #000}.aic-hud-tl{top:24px;left:24px}.aic-hud-tr{top:22px;right:22px;display:flex;align-items:center;gap:8px}.aic-hud-br{right:25px;bottom:20px;color:rgba(238,240,235,.38)}
@@ -3,8 +3,10 @@ body[data-prts-skin="agent"] {
3
3
  color-scheme: light;
4
4
  color: #111214;
5
5
  background: #fff;
6
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
7
- "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
6
+ /* DSH 0.2.1 lets the user pick a font list; --dsw-font-family leads with it,
7
+ so the skin keeps that choice and only supplies the fallback stack. */
8
+ font-family: var(--dsw-font-family, -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
9
+ "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif);
8
10
  }
9
11
  body[data-prts-skin="agent"] > :has(> [data-shell-overlay]) { position: relative; z-index: 1; }
10
12
  .prts-agent-scene { position: fixed; z-index: 0; inset: 0; display: none; overflow: hidden;
@@ -112,11 +114,11 @@ body[data-prts-skin="agent"] .prts-evidence-layer{display:block}.prts-evidence-s
112
114
  .prts-agent-scene .prts-empty-hero{position:fixed;z-index:2;top:var(--agent-hero-top);right:var(--agent-content-right);left:var(--agent-content-left);text-align:center;transition:opacity .58s ease,transform .72s cubic-bezier(.22,.8,.24,1),filter .58s ease}.prts-agent-scene .prts-hero-identity{position:relative;top:auto;left:auto;display:inline-flex;width:auto;transform:none;flex-direction:column;align-items:flex-start;text-align:left;filter:drop-shadow(0 2px 12px rgba(255,255,255,.95))}.prts-agent-scene .prts-hero-wordmark{position:relative;display:flex;align-items:flex-start}.prts-agent-scene .prts-hero-wordmark svg{display:block;width:clamp(250px,31vw,470px);height:auto}.prts-agent-scene .prts-hero-wordmark em{position:absolute;top:1px;left:calc(100% + 9px);padding:0 6px;border:1px solid rgba(17,18,20,.36);border-radius:2px;color:rgba(255,255,255,.88);background:rgba(17,18,20,.82);font:600 8px/16px var(--agent-mono);letter-spacing:.08em;white-space:nowrap}.prts-agent-scene .prts-hero-identity small{display:flex;align-items:center;gap:9px;margin-top:11px;color:#111214;font:9px/15px var(--agent-mono);letter-spacing:.035em}.prts-agent-scene .prts-hero-identity small s{color:#858a91;text-decoration-color:#f25a5a}.prts-agent-scene .prts-empty-hero h2{margin:16px 0 7px;font-size:26px;line-height:34px;font-weight:500;letter-spacing:-.4px}.prts-agent-scene .prts-empty-hero>p{max-width:600px;margin:0 auto;color:#62666c;font-size:14px;line-height:22px}
113
115
  .prts-agent-scene[data-phase="active"] .prts-empty-hero{opacity:0;transform:translateY(-34px) scale(.96);filter:blur(3px)}.prts-agent-scene[data-phase="active"] .prts-cpu-assembly{opacity:0;translate:0 -148px;transform:translateX(-50%);filter:blur(5px)}.prts-agent-scene[data-phase="active"] :is(.prts-trace-query,.prts-trace-source,.prts-trace-stack,.prts-node-plan,.prts-node-read,.prts-node-recall,.prts-node-verify,.prts-system-ticker){opacity:1}.prts-agent-scene[data-phase="active"] :is(.prts-trace-source,.prts-node-recall,.prts-node-verify,.prts-system-ticker){translate:7vw 8px}.prts-agent-scene[data-phase="active"] .prts-node-plan{opacity:.48}
114
116
  .prts-agent-scene[data-phase="leaving"] .prts-empty-hero{opacity:0;transform:translateY(-34px) scale(.96);filter:blur(3px)}.prts-agent-scene[data-phase="leaving"] .prts-cpu-assembly{opacity:0;translate:0 -118px;transform:translateX(-50%);filter:blur(4px)}.prts-agent-scene[data-phase="leaving"] :is(.prts-trace-query,.prts-trace-source,.prts-trace-stack,.prts-node-plan,.prts-node-read,.prts-node-recall,.prts-node-verify,.prts-system-ticker){opacity:1}.prts-agent-scene[data-phase="leaving"] :is(.prts-trace-source,.prts-node-recall,.prts-node-verify,.prts-system-ticker){translate:7vw 8px}.prts-agent-scene[data-phase="leaving"] .prts-node-plan{opacity:.48}
115
- body[data-prts-skin="agent"]:has(.prts-agent-scene[data-page="conversation"]) :has(> [data-shell-overlay])>div:nth-of-type(1){background:rgba(250,250,247,.045)!important;box-shadow:none!important;backdrop-filter:none!important}
116
- body[data-prts-skin="agent"]:has(.prts-agent-scene[data-page="conversation"]) :has(> [data-shell-overlay])>div:nth-of-type(1) :is(span,b,small,p,h1,h2,h3,label):not([role="dialog"] *){color:transparent!important;background:linear-gradient(180deg,rgba(250,250,247,.96) 0,rgba(250,250,247,.94) 49vh,rgba(20,22,25,.96) 49.08vh,rgba(20,22,25,.96) 76vh) fixed;background-clip:text;-webkit-background-clip:text}body[data-prts-skin="agent"]:has(.prts-agent-scene[data-page="conversation"]) :has(> [data-shell-overlay])>div:nth-of-type(1) svg:not([role="dialog"] *){color:rgba(250,250,247,.92)!important;mix-blend-mode:difference}body[data-prts-skin="agent"]:has(.prts-agent-scene[data-page="conversation"]) [data-slot="sidebar.brand.name"]::before,body[data-prts-skin="agent"]:has(.prts-agent-scene[data-page="conversation"]) [data-slot="sidebar.brand.name"]::after{color:transparent;background:linear-gradient(180deg,rgba(250,250,247,.96) 0,rgba(250,250,247,.94) 49vh,rgba(20,22,25,.96) 49.08vh,rgba(20,22,25,.96) 76vh) fixed;background-clip:text;-webkit-background-clip:text}
117
- body[data-prts-skin="agent"] :has(> [data-shell-overlay])>div:nth-of-type(1) [role="dialog"]{--dsw-alias-button-elevated-fill:rgba(255,255,255,.92);--dsw-alias-button-floating-hover:#efefeb;--dsw-alias-label-primary:#111214;--dsw-alias-label-secondary:#34373b;--dsw-alias-label-tertiary:#62666c;--dsw-alias-label-caption:#858a91;--dsw-alias-border-l1:rgba(17,18,20,.08);--dsw-alias-border-l2:rgba(17,18,20,.13);--dsw-alias-bg-base:#fff;--dsw-alias-bg-layer-1:#f4f4f1;--dsw-alias-bg-layer-2:#fff;--dsw-alias-bg-layer-3:#fff;--dsw-alias-interactive-bg-hover:rgba(17,18,20,.055);--dsw-specific-sidebar-nav-item-hover:rgba(17,18,20,.055);--dsw-specific-sidebar-nav-item-active:rgba(17,18,20,.095);color:#111214!important;background:#fff!important}
118
- body[data-prts-skin="agent"] :has(> [data-shell-overlay])>div:nth-of-type(1) [role="dialog"] :is(span,b,small,p,h1,h2,h3,label){color:inherit!important;background:none!important;background-clip:border-box!important;-webkit-background-clip:border-box!important;-webkit-text-fill-color:currentColor!important}body[data-prts-skin="agent"] :has(> [data-shell-overlay])>div:nth-of-type(1) [role="dialog"] svg{color:currentColor!important;mix-blend-mode:normal!important}
119
- body[data-prts-skin="agent"] :has(> [data-shell-overlay])>div:nth-of-type(1) button:is([aria-label="新会话"],[aria-label="新建会话"],[aria-label="New chat"],[aria-label="New session"],[aria-label="New conversation"]):has(>svg){border-color:rgba(255,255,255,.1)!important;color:#f7f7f4!important;background:rgba(255,255,255,.1)!important}
117
+ body[data-prts-skin="agent"]:has(.prts-agent-scene[data-page="conversation"]) :has(> [data-shell-overlay])>div:has(> [data-slot="sidebar"]){background:rgba(250,250,247,.045)!important;box-shadow:none!important;backdrop-filter:none!important}
118
+ body[data-prts-skin="agent"]:has(.prts-agent-scene[data-page="conversation"]) :has(> [data-shell-overlay])>div:has(> [data-slot="sidebar"]) :is(span,b,small,p,h1,h2,h3,label):not([role="dialog"] *){color:transparent!important;background:linear-gradient(180deg,rgba(250,250,247,.96) 0,rgba(250,250,247,.94) 49vh,rgba(20,22,25,.96) 49.08vh,rgba(20,22,25,.96) 76vh) fixed;background-clip:text;-webkit-background-clip:text}body[data-prts-skin="agent"]:has(.prts-agent-scene[data-page="conversation"]) :has(> [data-shell-overlay])>div:has(> [data-slot="sidebar"]) svg:not([role="dialog"] *){color:rgba(250,250,247,.92)!important;mix-blend-mode:difference}body[data-prts-skin="agent"]:has(.prts-agent-scene[data-page="conversation"]) [data-slot="sidebar.brand.name"]::before,body[data-prts-skin="agent"]:has(.prts-agent-scene[data-page="conversation"]) [data-slot="sidebar.brand.name"]::after{color:transparent;background:linear-gradient(180deg,rgba(250,250,247,.96) 0,rgba(250,250,247,.94) 49vh,rgba(20,22,25,.96) 49.08vh,rgba(20,22,25,.96) 76vh) fixed;background-clip:text;-webkit-background-clip:text}
119
+ body[data-prts-skin="agent"] :has(> [data-shell-overlay])>div:has(> [data-slot="sidebar"]) [role="dialog"]{--dsw-alias-button-elevated-fill:rgba(255,255,255,.92);--dsw-alias-button-floating-hover:#efefeb;--dsw-alias-label-primary:#111214;--dsw-alias-label-secondary:#34373b;--dsw-alias-label-tertiary:#62666c;--dsw-alias-label-caption:#858a91;--dsw-alias-border-l1:rgba(17,18,20,.08);--dsw-alias-border-l2:rgba(17,18,20,.13);--dsw-alias-bg-base:#fff;--dsw-alias-bg-layer-1:#f4f4f1;--dsw-alias-bg-layer-2:#fff;--dsw-alias-bg-layer-3:#fff;--dsw-alias-interactive-bg-hover:rgba(17,18,20,.055);--dsw-specific-sidebar-nav-item-hover:rgba(17,18,20,.055);--dsw-specific-sidebar-nav-item-active:rgba(17,18,20,.095);color:#111214!important;background:#fff!important}
120
+ body[data-prts-skin="agent"] :has(> [data-shell-overlay])>div:has(> [data-slot="sidebar"]) [role="dialog"] :is(span,b,small,p,h1,h2,h3,label){color:inherit!important;background:none!important;background-clip:border-box!important;-webkit-background-clip:border-box!important;-webkit-text-fill-color:currentColor!important}body[data-prts-skin="agent"] :has(> [data-shell-overlay])>div:has(> [data-slot="sidebar"]) [role="dialog"] svg{color:currentColor!important;mix-blend-mode:normal!important}
121
+ body[data-prts-skin="agent"] :has(> [data-shell-overlay])>div:has(> [data-slot="sidebar"]) button:is([aria-label="新会话"],[aria-label="新建会话"],[aria-label="New chat"],[aria-label="New session"],[aria-label="New conversation"]):has(>svg){border-color:rgba(255,255,255,.1)!important;color:#f7f7f4!important;background:rgba(255,255,255,.1)!important}
120
122
  /* DSH 会话行保持原生单行 flex 语义。过去强制改成两行 grid 会把状态
121
123
  的 screen-reader 文本挤回可视区,形成标题与“进行中”重叠。 */
122
124
  body[data-prts-skin="agent"] div[role="treeitem"][aria-selected]:has(>span:nth-child(4)){position:relative;display:flex!important;align-items:center!important;gap:0!important;box-sizing:border-box;height:44px!important;margin:3px 0!important;padding:6px 10px!important;border-radius:12px!important}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prts-terrarchive",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -43,6 +43,8 @@
43
43
  "bin/rhine-detail-baker.ts",
44
44
  "docs/endfield-official-i18n.md",
45
45
  "docs/web-access.md",
46
+ "bin/build-mainline-catalog.py",
47
+ "docs/endfield-mainline-navigation.md",
46
48
  "bin/build-runtime.mjs",
47
49
  "bin/check-runtime.mjs"
48
50
  ],
@@ -65,6 +67,7 @@
65
67
  "homepage": "https://prts.chat",
66
68
  "bugs": "https://github.com/HTian-qwq/prts-terrarchive/issues",
67
69
  "dsh": {
70
+ "manifestVersion": 1,
68
71
  "bundle": {
69
72
  "patch": "./cordis.patch.yml"
70
73
  },
@@ -86,13 +89,14 @@
86
89
  }
87
90
  },
88
91
  "engines": {
89
- "node": ">=22.19"
92
+ "node": ">=22.19",
93
+ "dsh": ">=0.2.0-rc.1"
90
94
  },
91
95
  "scripts": {
92
96
  "test": "node --test --test-concurrency=1 test/*.test.js",
93
97
  "pack:map": "node bin/pack-map-assets.mjs",
94
98
  "pack:map:restore": "node bin/pack-map-assets.mjs --restore",
95
- "check": "node --check src/index.js && node --check src/search.js && node --check src/search-projection.js && node --check src/read.js && node --check src/wiki.js && node --check src/store.js && node --check src/source-map.js && node --check src/cloud-projection.js && node --check src/evidence-state.js && node --check src/entity-routing.js && node --check src/entity-recognizer.js && node --check src/timeline.js && node --check src/cloud.js && node --check src/release-compatibility.js && node --check src/installer.js && node --check src/state.js && node --check src/ui.js && node --check src/skill.js && node --check lib/client.js && node --check bin/install.js && node --check bin/pack-map-assets.mjs && node --check presets/definition.js && node --check presets/register.js && node --check src/release-watch.js && node --check src/archive-presentation.js && node --check bin/preview-rhine.mjs && node --check src/i18n.js && node --check src/localization-format.js && node --check presets/composition.js && node --check src/tools.js && node --check src/composition-skill.js",
99
+ "check": "node --check src/index.js && node --check src/navigation.js && node --check src/search.js && node --check src/search-projection.js && node --check src/read.js && node --check src/wiki.js && node --check src/store.js && node --check src/source-map.js && node --check src/cloud-projection.js && node --check src/evidence-state.js && node --check src/entity-routing.js && node --check src/entity-recognizer.js && node --check src/timeline.js && node --check src/cloud.js && node --check src/release-compatibility.js && node --check src/installer.js && node --check src/state.js && node --check src/ui.js && node --check src/skill.js && node --check lib/client.js && node --check bin/install.js && node --check bin/pack-map-assets.mjs && node --check presets/definition.js && node --check presets/register.js && node --check src/release-watch.js && node --check src/archive-presentation.js && node --check bin/preview-rhine.mjs && node --check src/i18n.js && node --check src/localization-format.js && node --check presets/composition.js && node --check src/tools.js && node --check src/composition-skill.js && node --check src/tool-args.js",
96
100
  "install:prts": "node bin/install.js",
97
101
  "bake:rhine-details": "node bin/bake-rhine-details.mjs",
98
102
  "build:rhine": "npm run bake:rhine-details && tsc -p tsconfig.rhine.json && vite build --config vite.rhine.config.ts",