@modesto_ma/dsh-guanxiang 0.2.0-beta.2 → 0.2.0-beta.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 +9 -9
- package/lib/client.js +1 -1
- package/lib/client.js.map +1 -1
- package/lib/index.js +109 -138
- package/lib/index.js.map +1 -1
- package/package.json +2 -1
- package/src/client/page.tsx +1 -1
- package/src/config.ts +2 -2
- package/src/index.ts +2 -2
- package/src/repos/registry.ts +2 -4
- package/src/service.ts +2 -0
- package/src/skill-update/git.ts +3 -76
- package/src/skill-update/repos.ts +51 -0
- package/src/skill-update/tool.ts +66 -31
package/README.md
CHANGED
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
- **代码快照不可变。** 子 Agent 在 `<reposDir>/.snapshots/<仓库名>/` 下按提交创建的 `git worktree` 快照里工作。快照创建后不再改动,同一提交的派发共用一份;没有分析在用、且已不是最新提交的快照会被删除。
|
|
65
65
|
- **运行目录。** 每次派发在父会话目录下创建 `.guanxiang/runs/<runId>/<序号>-<应用 id>/`,下载的日志放在这里,子 Agent 也只在这里写文件;应用仓库对子 Agent 只读。
|
|
66
66
|
- **等待式派发。** 工具等待所有子 Agent 结束后一次返回,一条消息对应一张完整回复;超过派发超时或调用被取消时停止仍在运行的子 Agent。子会话中不提供派发工具。
|
|
67
|
-
- **SKILL 改进(可选,默认关闭)。** 子 Agent 发现应用的日志分析 SKILL
|
|
67
|
+
- **SKILL 改进(可选,默认关闭)。** 子 Agent 发现应用的日志分析 SKILL 有欠缺时,可以在运行目录写出修改提议;经用户授权后,观象经 [dsh-repo](https://github.com/modestoma/dsh-repo) 把它提交到应用仓库的新分支并创建合并请求(GitLab MR 或 GitHub PR),见 [SKILL 改进](#skill-改进)。
|
|
68
68
|
|
|
69
69
|
## 安装与配置
|
|
70
70
|
|
|
@@ -114,7 +114,7 @@ npm 发行包已包含构建产物;本地 `link:` 安装前必须先执行 `pn
|
|
|
114
114
|
enabled: false # 默认关闭
|
|
115
115
|
maxFiles: 16 # 一次提议最多新增或修改的文件数
|
|
116
116
|
maxFileBytes: 262144 # 提议中单个文件的大小上限
|
|
117
|
-
skillUpdateAuthor: # 可选:SKILL
|
|
117
|
+
skillUpdateAuthor: # 可选:SKILL 改进提交的作者;省略时是 dsh-repo 中该主机令牌的主人
|
|
118
118
|
name: 观象
|
|
119
119
|
email: guanxiang@example.com
|
|
120
120
|
analyze: # 日志平台分析接口,见下文
|
|
@@ -126,7 +126,7 @@ npm 发行包已包含构建产物;本地 `link:` 安装前必须先执行 `pn
|
|
|
126
126
|
|
|
127
127
|
### 访问令牌
|
|
128
128
|
|
|
129
|
-
用 https 地址拉取 GitLab 等私有仓库时,可以配置个人访问令牌(GitLab 需要 `read_repository`
|
|
129
|
+
用 https 地址拉取 GitLab 等私有仓库时,可以配置个人访问令牌(GitLab 需要 `read_repository` 权限;[SKILL 改进](#skill-改进) 的提交改由 dsh-repo 的令牌完成,这里不需要写权限):
|
|
130
130
|
|
|
131
131
|
- **配置只写名称。** `gitCredentials` 的每一项把一个地址前缀(`https://主机[:端口][/路径]`)对应到一个令牌名称 `tokenEnv`;地址在前缀下的 https 仓库使用该令牌,多个前缀匹配时取路径最长的。ssh、`user@host:path` 和本地路径不受影响。
|
|
132
132
|
- **令牌值在 DSH 凭据库。** 令牌通过 DSH 的 `ctx.credentials` 读取(默认组合加载的 `@deepseek-ai/dsh-credentials-local`,文件 `$DSH_HOME/.credentials.yaml`,仅本机用户可读),可以在设置面板的「访问令牌」分页保存,也可以设置同名环境变量或写进 `.env`。每次拉取都重新读取,更换令牌不用重启。面板接口只接受已保存的配置引用的名称,也从不返回令牌值。
|
|
@@ -174,19 +174,19 @@ skill: log-analysis # 对应 .dsh/skills/log-analysis/SKILL.md
|
|
|
174
174
|
|
|
175
175
|
## SKILL 改进
|
|
176
176
|
|
|
177
|
-
开启 `skillUpdates.enabled`(设置面板「高级」→「SKILL 改进」)后,分析中发现的 SKILL
|
|
177
|
+
开启 `skillUpdates.enabled`(设置面板「高级」→「SKILL 改进」)后,分析中发现的 SKILL 欠缺可以经用户授权后提交为合并请求。提交和创建合并请求经 [dsh-repo](https://github.com/modestoma/dsh-repo) 的 `dshRepos` 服务完成(需要 dsh-repo 0.1.0-beta.2 及以上):需要同时安装 dsh-repo,并在它的 `hosts` 中配置应用仓库所在的主机和令牌;没有该服务或版本不符时工具报错。
|
|
178
178
|
|
|
179
179
|
1. **子 Agent 写提议。** 子 Agent 的任务消息多出一节说明:把要改的文件从 `.dsh/skills/<skill>/` 复制到运行目录的 `skill-proposal/files/`(保持相对路径)后修改,理由写进 `skill-proposal/reason.md`。仓库对子 Agent 仍然只读。
|
|
180
180
|
2. **派发结果标出提议。** 派发结束后,观象检查已完成任务的提议:只接受普通文件和受限的文件名、UTF-8 文本、文件数与大小上限,`SKILL.md` 不能设置 `user-invocable: false`。合格的提议在结果中给出改动行数,并在运行目录写出 `skill-proposal.diff`;不合格的给出原因。
|
|
181
181
|
3. **父 Agent 展示并提交。** 入口 SKILL 让父 Agent 在汇总回复后附上改动和 diff,再调用 `guanxiang_propose_skill`(参数为任务的运行目录和一句话摘要)。只接受本次 DSH 运行中由同一会话派发过的任务;应用、仓库和分析时的提交取自派发记录。
|
|
182
|
-
4. **请求授权。** 工具通过 DSH 的审批服务(`ctx.approval`,`@deepseek-ai/dsh-user-approval
|
|
183
|
-
5.
|
|
182
|
+
4. **请求授权。** 工具通过 DSH 的审批服务(`ctx.approval`,`@deepseek-ai/dsh-user-approval`)请求一次性授权,说明将提交的仓库、分支、目标分支、改动文件和理由。经 dsh_channels 使用时显示为飞书决策卡片,在 DSH Web 中显示为审批提示;观象与 dsh_channels 之间没有代码依赖。只有「允许」才提交;拒绝、撤回或没有可回答的界面时都不提交。会话的审批策略为 `never`(例如 DSH 的「完全访问」权限模式)时请求一律被拒绝,所以要在「询问」类权限模式下使用;DSH 组合没有审批服务时工具报错。
|
|
183
|
+
5. **提交新分支并创建合并请求。** 观象进程(不是 Agent)经 `dshRepos` 以分析时的提交为起点建新分支 `guanxiang/skill-<应用 id>-<树对象前缀>`,提交 `.dsh/skills/<skill>/` 下有改动的文件,再创建合入跟踪分支的合并请求,返回它的链接。同一改动的分支已存在时不再请求授权,也不提交;等待授权期间分支被别人建出时同样不提交。从不提交到已有分支或默认分支,合并由仓库的评审流程决定;合并后下次 `/guanxiang` 拉取即生效。提交成功但合并请求创建失败时,工具返回分支和失败原因,可以在代码托管平台上手动创建。
|
|
184
184
|
|
|
185
185
|
注意:
|
|
186
186
|
|
|
187
|
-
-
|
|
188
|
-
-
|
|
189
|
-
-
|
|
187
|
+
- 支持 GitLab(包括自建实例)和 GitHub。应用仓库的 git 地址(https、ssh 或 `user@host:path`)要能被 dsh-repo 识别为已配置主机上的仓库;dsh-repo 的令牌在 GitLab 上需要 `api` 权限,在 GitHub 上需要 Contents 和 Pull requests 的读写权限。
|
|
188
|
+
- 有写权限的令牌可以改动它能访问的所有项目。建议用只覆盖应用仓库的项目或组访问令牌,设置过期时间,用 dsh-repo 的 `repos` 限定范围,并保护应用仓库的默认分支。
|
|
189
|
+
- 合并请求以 dsh-repo 令牌主人的身份创建,提交作者是 `skillUpdateAuthor`,省略时也是令牌主人。飞书群里点「允许」的人可能不是令牌主人;合并请求描述写明了来源会话与分析提交。
|
|
190
190
|
- 日志内容不可信,可能诱导模型写出不当的 SKILL。观象只限制改动范围,内容需要授权的人和合并请求的评审者把关。
|
|
191
191
|
|
|
192
192
|
## 日志平台分析接口
|
package/lib/client.js
CHANGED
|
@@ -1418,7 +1418,7 @@ window.__ModuleLoader__.load({
|
|
|
1418
1418
|
})]
|
|
1419
1419
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1420
1420
|
className: "gx__rowSummary",
|
|
1421
|
-
children: "子 Agent 发现应用的日志分析 SKILL
|
|
1421
|
+
children: "子 Agent 发现应用的日志分析 SKILL 有欠缺时可以写出修改提议;经用户授权后,观象经 dsh-repo 把它提交到新分支并创建合并请求(GitLab 或 GitHub,需要安装 dsh-repo 并配置该仓库主机的令牌)。"
|
|
1422
1422
|
})]
|
|
1423
1423
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1424
1424
|
className: "gx__rowCtl",
|
package/lib/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":[],"sources":["../src/client/icon.tsx","../src/settings/contract.ts","../src/client/api.ts","../src/client/page.tsx","../src/client/styles.ts","../src/client/index.ts"],"sourcesContent":["/**\n * 左侧栏「观象」行的装饰图标;行本身负责可访问名称(列表注册的 label)。\n *\n * @module dsh-guanxiang/client/icon\n */\n\n/** Owner share of `sidebar.panellist`: requested square edge and selection state. */\nexport interface GuanxiangIconProps {\n size: number\n active: boolean\n}\n\n/**\n * Eye-over-waveform glyph drawn in `currentColor`.\n * @param props - the sidebar's icon share.\n * @returns decorative icon.\n */\nexport function GuanxiangIcon({ size }: GuanxiangIconProps): JSX.Element {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={1.6} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M2.5 10c2.4-3.6 5.6-5.4 9.5-5.4s7.1 1.8 9.5 5.4c-2.4 3.6-5.6 5.4-9.5 5.4S4.9 13.6 2.5 10Z\" />\n <circle cx=\"12\" cy=\"10\" r=\"2.4\" />\n <path d=\"M3 19.5h3l2-2.5 2.5 4 3-6 2.5 4.5 1.5-2h3.5\" />\n </svg>\n )\n}\n","/**\n * 设置面板与 Host 路由共用的路由常量和 JSON 结构。浏览器端 bundle 也会\n * 编译本文件,因此这里只放类型和常量,不 import 任何 Node 模块。\n *\n * @module dsh-guanxiang/settings/contract\n */\n\n/** GET:面板所需的全部状态(生效设置、默认值、仓库与应用)。 */\nexport const STATE_ROUTE = '/guanxiang/state'\n/** PUT:保存可编辑设置;DELETE:清除面板覆盖、恢复 cordis.yml 默认值。 */\nexport const SETTINGS_ROUTE = '/guanxiang/settings'\n/** POST:立即重新拉取全部仓库,或 body `{ url }` 指定的一个仓库。 */\nexport const SYNC_ROUTE = '/guanxiang/sync'\n/** PUT:body `{ tokenEnv, value }` 把令牌存入 DSH 凭据库;DELETE:body `{ tokenEnv }` 删除已存的值。只接受已保存的访问令牌配置引用的名称和分析接口令牌的名称。 */\nexport const TOKEN_ROUTE = '/guanxiang/token'\n\n/**\n * POST:日志平台分析接口(Bearer 令牌鉴权,不走 DSH 登录)。它在 DSH 的\n * `/api` 命名空间之外,网关可以把它和需要登录的 DSH 接口分开暴露。\n */\nexport const ANALYZE_ROUTE = '/open-api/logalyze'\n\n/** One configured application repository. */\nexport interface RepoSpec {\n /** Git remote address, cloned with the host machine's existing git credentials or a matching {@link GitCredentialSpec}. */\n url: string\n /** Remote branch to follow; omitted follows the remote's default branch. */\n branch?: string\n}\n\n/** Credential reference grammar of `@deepseek-ai/dsh-credentials` (a POSIX shell identifier), which {@link GitCredentialSpec.tokenEnv} follows. */\nexport const TOKEN_ENV_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/\n\n/** HTTPS access token used for the repositories under one address prefix. */\nexport interface GitCredentialSpec {\n /** `https://host[:port][/path]` (or `http://`) prefix; repository addresses under it use this token. */\n url: string\n /** Display name the panel shows for this token; omitted shows the address. */\n alias?: string\n /** HTTP username sent with the token; GitLab personal access tokens accept `oauth2`. */\n username: string\n /** Credential reference (environment-variable name) whose value in DSH's credential store is the token. */\n tokenEnv: string\n}\n\n/** Log URL download policy. */\nexport interface DownloadSettings {\n /** Allowed host names; `example.com` also admits its subdomains. Empty disables URL downloads. */\n allowedHosts: string[]\n /** Per-file byte ceiling. */\n maxBytes: number\n /** Per-file download timeout in milliseconds. */\n timeoutMs: number\n}\n\n/** Application SKILL improvement proposals that children may write and the top-level agent may submit as merge requests. */\nexport interface SkillUpdateSettings {\n /** Whether children are told how to propose SKILL changes and top-level agents are offered `guanxiang_propose_skill`. */\n enabled: boolean\n /** Most files one proposal may add or change. */\n maxFiles: number\n /** Largest proposed file, in bytes. */\n maxFileBytes: number\n}\n\n/** The log-platform analyze API ({@link ANALYZE_ROUTE}). */\nexport interface AnalyzeSettings {\n /** Whether the API accepts requests; switched off it answers 404. */\n enabled: boolean\n}\n\n/** The settings the Web panel can override; every field is required on the wire. */\nexport interface EditableSettings {\n /** Absolute directory holding the cloned repositories (`~` expands to the home directory). */\n reposDir: string\n /** Application repositories to clone and keep updated. */\n repos: RepoSpec[]\n /** HTTPS access tokens by address prefix; the token values stay in DSH's credential store. */\n gitCredentials: GitCredentialSpec[]\n /** Minimum age of a repository's last sync before loading `/guanxiang` syncs it again, in milliseconds; 0 syncs on every load. */\n fetchIntervalMs: number\n /** Maximum number of child analyses one dispatch may start. */\n maxAppsPerRequest: number\n /** Whole-dispatch wait budget in milliseconds; children still running then are stopped. */\n dispatchTimeoutMs: number\n /** URL download policy. */\n download: DownloadSettings\n /** SKILL improvement proposals. */\n skillUpdates: SkillUpdateSettings\n /** Log-platform analyze API. */\n analyze: AnalyzeSettings\n}\n\n/** Keys of {@link EditableSettings}, in panel order. */\nexport const EDITABLE_KEYS = ['reposDir', 'repos', 'gitCredentials', 'fetchIntervalMs', 'maxAppsPerRequest', 'dispatchTimeoutMs', 'download', 'skillUpdates', 'analyze'] as const satisfies readonly (keyof EditableSettings)[]\n\n/** One editable key. */\nexport type EditableKey = (typeof EDITABLE_KEYS)[number]\n\n/** Application description read from `<repo>/.dsh/guanxiang.yaml`. */\nexport interface AppManifest {\n /** Registry id the dispatch tool and analysis requests address. */\n id: string\n /** Display name, also the child agent's label. */\n name: string\n /** What the application does, used for intent recognition. */\n description: string\n /** Other names users call the application by. */\n aliases: string[]\n /** Strings that identify this application's log lines (tags, process names, class names). */\n logHints: string[]\n /** Project skill name under `.dsh/skills/<skill>/SKILL.md` that analyzes this application's logs. */\n skill: string\n}\n\n/** Lifecycle of one repository checkout. */\nexport type RepoPhase = 'pending' | 'syncing' | 'ready' | 'failed'\n\n/** One repository as the panel shows it. */\nexport interface RepoStatusWire {\n url: string\n branch?: string\n /** Absolute directory of the fetch-only clone; children work in commit snapshots under `<reposDir>/.snapshots/`. */\n dir: string\n phase: RepoPhase\n /** Latest synced commit, the one the catalog describes and new dispatches use. */\n commit?: string\n /** Committer date of {@link commit}, ISO 8601. */\n commitTime?: string\n /** Last completed sync attempt, epoch milliseconds. */\n syncedAt?: number\n /** Application description read from {@link commit}. */\n app?: AppManifest\n /** Why the repository is unusable (`failed`), or why the last update failed while an older commit stays usable (`ready`). */\n error?: string\n /** Whether the application is offered to intent recognition and dispatch. */\n available: boolean\n /** Child analyses currently running in snapshots of this repository. */\n activeRuns: number\n}\n\n/** Whether one referenced token has a value — never the value. */\nexport interface TokenStatusWire {\n tokenEnv: string\n /** Whether resolving the reference currently returns a value. */\n configured: boolean\n /** Credential store layer supplying the value (`file`, `env`, `project-env`, `user-env`); absent while unconfigured. */\n source?: string\n /** Whether the panel can store a value for this reference. */\n writable: boolean\n /** Why the credential store could not describe the reference. */\n error?: string\n}\n\n/** Credential store view of the panel. */\nexport interface CredentialsWire {\n /** Whether the DSH composition provides `ctx.credentials`; without it tokens cannot be stored or read. */\n available: boolean\n /** One entry per distinct `tokenEnv` of the effective settings; empty while unavailable. */\n tokens: TokenStatusWire[]\n}\n\n/**\n * Whether dsh-channels provides the `feishuTopics` service the analyze API\n * posts through: `missing` while it is not loaded (or older than 0.8, which\n * serves the API itself), `incompatible` when its contract version is not\n * the one this plugin speaks.\n */\nexport type TopicsAvailability = 'ready' | 'missing' | 'incompatible'\n\n/** Analyze API view of the panel. */\nexport interface AnalyzeWire {\n /** Route the log platform posts to. */\n route: string\n /** Credential reference (`analyzeTokenRef`) holding the bearer token. */\n tokenEnv: string\n /** Token status; absent while the DSH composition has no credential store. */\n token?: TokenStatusWire\n topics: TopicsAvailability\n}\n\n/** `GET /guanxiang/state` response. */\nexport interface StateWire {\n /** Effective settings: cordis.yml values with panel overrides applied. */\n settings: EditableSettings\n /** cordis.yml values before panel overrides. */\n defaults: EditableSettings\n /** Keys the panel currently overrides. */\n overridden: EditableKey[]\n /** Why the overlay file was ignored (unreadable or invalid); panel saves replace it. */\n overlayError?: string\n repos: RepoStatusWire[]\n credentials: CredentialsWire\n analyze: AnalyzeWire\n}\n\n/** Successful mutation response. */\nexport interface MutationOk {\n ok: true\n state: StateWire\n}\n\n/** Failed request response. */\nexport interface MutationError {\n ok: false\n error: string\n}\n","/**\n * 设置面板的同源 HTTP 客户端,直接请求 Host 半侧注册的 `/guanxiang/*` 路由。\n *\n * @module dsh-guanxiang/client/api\n */\n\nimport { SETTINGS_ROUTE, STATE_ROUTE, SYNC_ROUTE, TOKEN_ROUTE } from '../settings/contract.ts'\nimport type { EditableSettings, MutationError, MutationOk, StateWire } from '../settings/contract.ts'\n\n/**\n * Error text of a value thrown by a request.\n * @param error - thrown value.\n * @returns message.\n */\nexport function messageOf(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n\n/**\n * Fetch one Host route. Routes are absolute pathnames, but the browser\n * addresses them relative to the DSH document so a reverse proxy that mounts\n * DSH under a prefix still routes them with its scoped login cookie.\n */\nasync function request<T>(route: string, init?: RequestInit): Promise<T> {\n let response: Response\n try {\n response = await fetch(route.slice(1), {\n cache: 'no-store',\n credentials: 'same-origin',\n ...init,\n headers: { accept: 'application/json', ...init?.body === undefined ? {} : { 'content-type': 'application/json' } },\n })\n } catch (error) {\n throw new Error(`无法连接设置接口:${messageOf(error)}`)\n }\n const text = await response.text()\n let body: unknown\n try {\n body = JSON.parse(text)\n } catch {\n // Non-JSON bodies (proxy errors) are reported by HTTP status below.\n throw new Error(`HTTP ${response.status}`)\n }\n if (!response.ok) {\n const error = (body as Partial<MutationError>).error\n throw new Error(typeof error === 'string' && error !== '' ? error : `HTTP ${response.status}`)\n }\n return body as T\n}\n\n/** @returns the panel state. */\nexport function fetchState(): Promise<StateWire> {\n return request<StateWire>(STATE_ROUTE)\n}\n\n/**\n * Save the complete editable settings.\n * @param settings - settings to persist.\n * @returns the new state.\n */\nexport async function saveSettings(settings: EditableSettings): Promise<StateWire> {\n return (await request<MutationOk>(SETTINGS_ROUTE, { method: 'PUT', body: JSON.stringify(settings) })).state\n}\n\n/** @returns the state after removing every panel override. */\nexport async function resetSettings(): Promise<StateWire> {\n return (await request<MutationOk>(SETTINGS_ROUTE, { method: 'DELETE' })).state\n}\n\n/**\n * Re-sync one repository or all of them.\n * @param url - repository address; omitted syncs all.\n * @returns the state right after the sync started.\n */\nexport async function syncRepos(url?: string): Promise<StateWire> {\n return (await request<MutationOk>(SYNC_ROUTE, { method: 'POST', body: JSON.stringify(url === undefined ? {} : { url }) })).state\n}\n\n/**\n * Store an access token in DSH's credential store.\n * @param tokenEnv - credential reference named by a saved access-token configuration.\n * @param value - token value.\n * @returns the new state, which reports only whether the token is set.\n */\nexport async function saveToken(tokenEnv: string, value: string): Promise<StateWire> {\n return (await request<MutationOk>(TOKEN_ROUTE, { method: 'PUT', body: JSON.stringify({ tokenEnv, value }) })).state\n}\n\n/**\n * Remove a stored access token.\n * @param tokenEnv - credential reference named by a saved access-token configuration.\n * @returns the new state.\n */\nexport async function clearToken(tokenEnv: string): Promise<StateWire> {\n return (await request<MutationOk>(TOKEN_ROUTE, { method: 'DELETE', body: JSON.stringify({ tokenEnv }) })).state\n}\n","/**\n * 左侧栏「观象」主区页面:应用仓库、访问令牌、日志下载、分析接口、高级(含 SKILL 改进)五个\n * 分页,共用一份草稿和底部保存条;令牌值不进草稿,单独存入 DSH 凭据库。\n * 仓库拉取中时每 2 秒刷新状态。\n *\n * @module dsh-guanxiang/client/page\n */\n\nimport { useCallback, useEffect, useMemo, useState } from 'react'\nimport type { AnalyzeWire, EditableKey, EditableSettings, GitCredentialSpec, RepoSpec, RepoStatusWire, StateWire, TokenStatusWire } from '../settings/contract.ts'\nimport { clearToken, fetchState, messageOf, resetSettings, saveSettings, saveToken, syncRepos } from './api.ts'\n\n/** Sidebar label and page title. */\nexport const PANEL_TITLE = '观象'\n\nconst KB = 1024\nconst MB = 1024 * 1024\nconst MINUTE = 60 * 1000\n\ntype TabId = 'repos' | 'tokens' | 'download' | 'analyze' | 'advanced'\n\nconst TABS: readonly { id: TabId; label: string }[] = [\n { id: 'repos', label: '应用仓库' },\n { id: 'tokens', label: '访问令牌' },\n { id: 'download', label: '日志下载' },\n { id: 'analyze', label: '分析接口' },\n { id: 'advanced', label: '高级' },\n]\n\n/** Editable text form of the settings. */\ninterface Draft {\n reposDir: string\n repos: RepoSpec[]\n gitCredentials: GitCredentialSpec[]\n fetchIntervalMin: string\n maxAppsPerRequest: string\n dispatchTimeoutMin: string\n allowedHosts: string[]\n maxMb: string\n timeoutSec: string\n skillUpdatesEnabled: boolean\n skillMaxFiles: string\n skillMaxKb: string\n analyzeEnabled: boolean\n}\n\nfunction trimNumber(value: number): string {\n return String(Math.round(value * 100) / 100)\n}\n\nfunction toDraft(settings: EditableSettings): Draft {\n return {\n reposDir: settings.reposDir,\n repos: settings.repos.map(repo => ({ ...repo })),\n gitCredentials: settings.gitCredentials.map(credential => ({ ...credential })),\n fetchIntervalMin: trimNumber(settings.fetchIntervalMs / MINUTE),\n maxAppsPerRequest: String(settings.maxAppsPerRequest),\n dispatchTimeoutMin: trimNumber(settings.dispatchTimeoutMs / MINUTE),\n allowedHosts: [...settings.download.allowedHosts],\n maxMb: trimNumber(settings.download.maxBytes / MB),\n timeoutSec: trimNumber(settings.download.timeoutMs / 1000),\n skillUpdatesEnabled: settings.skillUpdates.enabled,\n skillMaxFiles: String(settings.skillUpdates.maxFiles),\n skillMaxKb: trimNumber(settings.skillUpdates.maxFileBytes / KB),\n analyzeEnabled: settings.analyze.enabled,\n }\n}\n\nfunction positive(text: string, label: string, allowZero = false): number {\n const value = Number(text.trim())\n if (text.trim() === '' || !Number.isFinite(value) || value < 0 || (!allowZero && value === 0)) throw new Error(`${label}必须是${allowZero ? '非负' : '正'}数`)\n return value\n}\n\nfunction fromDraft(draft: Draft): EditableSettings {\n const maxApps = positive(draft.maxAppsPerRequest, '单次应用数上限')\n if (!Number.isInteger(maxApps)) throw new Error('单次应用数上限必须是整数')\n const maxFiles = positive(draft.skillMaxFiles, '提议文件数上限')\n if (!Number.isInteger(maxFiles)) throw new Error('提议文件数上限必须是整数')\n return {\n reposDir: draft.reposDir.trim(),\n repos: draft.repos.map(repo => repo.branch === undefined || repo.branch.trim() === '' ? { url: repo.url.trim() } : { url: repo.url.trim(), branch: repo.branch.trim() }),\n gitCredentials: draft.gitCredentials.map(credential => ({\n url: credential.url.trim(),\n ...credential.alias === undefined || credential.alias.trim() === '' ? {} : { alias: credential.alias.trim() },\n username: credential.username.trim(),\n tokenEnv: credential.tokenEnv.trim(),\n })),\n fetchIntervalMs: Math.round(positive(draft.fetchIntervalMin, '更新间隔', true) * MINUTE),\n maxAppsPerRequest: maxApps,\n dispatchTimeoutMs: Math.round(positive(draft.dispatchTimeoutMin, '派发超时') * MINUTE),\n download: {\n allowedHosts: draft.allowedHosts.map(host => host.trim()).filter(host => host !== ''),\n maxBytes: Math.round(positive(draft.maxMb, '单文件大小上限') * MB),\n timeoutMs: Math.round(positive(draft.timeoutSec, '下载超时') * 1000),\n },\n skillUpdates: {\n enabled: draft.skillUpdatesEnabled,\n maxFiles,\n maxFileBytes: Math.round(positive(draft.skillMaxKb, '提议单文件大小上限') * KB),\n },\n analyze: { enabled: draft.analyzeEnabled },\n }\n}\n\nfunction sameSettings(draft: Draft, settings: EditableSettings): boolean {\n try {\n return JSON.stringify(fromDraft(draft)) === JSON.stringify(settings)\n } catch {\n // An unparsable draft differs from any saved settings.\n return false\n }\n}\n\nfunction formatTime(iso: string | number | undefined): string {\n if (iso === undefined) return ''\n const date = new Date(iso)\n return Number.isNaN(date.getTime()) ? '' : date.toLocaleString()\n}\n\nfunction phasePill(repo: RepoStatusWire | undefined): JSX.Element {\n if (repo === undefined) return <span className=\"gx__pill\"><span className=\"gx__dot\" />保存后拉取</span>\n if (repo.phase === 'syncing') return <span className=\"gx__pill gx__pill--warn\"><span className=\"gx__dot\" />拉取中</span>\n if (repo.available) return <span className=\"gx__pill gx__pill--ok\"><span className=\"gx__dot\" />就绪</span>\n if (repo.phase === 'ready' || repo.phase === 'failed') return <span className=\"gx__pill gx__pill--bad\"><span className=\"gx__dot\" />不可用</span>\n return <span className=\"gx__pill\"><span className=\"gx__dot\" />待拉取</span>\n}\n\nfunction Overridden({ keys, name }: { keys: readonly EditableKey[]; name: EditableKey }): JSX.Element | null {\n return keys.includes(name) ? <span className=\"gx__tag gx__tag--accent\">面板设置</span> : null\n}\n\n/**\n * Main-column page for the `main` slot.\n * @returns the page.\n */\nexport function GuanxiangPage(): JSX.Element {\n return (\n <section className=\"gx-page\" aria-label={PANEL_TITLE}>\n <div className=\"gx-page__content\">\n <GuanxiangPanel />\n </div>\n </section>\n )\n}\n\ntype Notice = { kind: 'ok' | 'error'; text: string } | undefined\n\n/**\n * Panel body: loads state, edits a draft, saves.\n * @returns the panel.\n */\nexport function GuanxiangPanel(): JSX.Element {\n const [state, setState] = useState<StateWire | undefined>()\n const [loadError, setLoadError] = useState<string | undefined>()\n const [draft, setDraft] = useState<Draft | undefined>()\n const [tab, setTab] = useState<TabId>('repos')\n const [busy, setBusy] = useState(false)\n const [notice, setNotice] = useState<Notice>()\n\n const adopt = useCallback((next: StateWire, resetDraft: boolean) => {\n setState(next)\n if (resetDraft) setDraft(toDraft(next.settings))\n }, [])\n\n const reload = useCallback(async (resetDraft: boolean) => {\n try {\n adopt(await fetchState(), resetDraft)\n setLoadError(undefined)\n } catch (error) {\n setLoadError(messageOf(error))\n }\n }, [adopt])\n\n useEffect(() => { void reload(true) }, [reload])\n\n const syncing = state?.repos.some(repo => repo.phase === 'syncing') === true\n useEffect(() => {\n if (!syncing) return\n const timer = setInterval(() => { void reload(false) }, 2000)\n return () => { clearInterval(timer) }\n }, [syncing, reload])\n\n const dirty = state !== undefined && draft !== undefined && !sameSettings(draft, state.settings)\n\n const run = async (action: () => Promise<StateWire>, success: string, resetDraft: boolean): Promise<StateWire | undefined> => {\n setBusy(true)\n setNotice(undefined)\n try {\n const next = await action()\n adopt(next, resetDraft)\n setNotice({ kind: 'ok', text: success })\n return next\n } catch (error) {\n setNotice({ kind: 'error', text: messageOf(error) })\n return undefined\n } finally {\n setBusy(false)\n }\n }\n\n const save = (): void => {\n if (draft === undefined) return\n let settings: EditableSettings\n try {\n settings = fromDraft(draft)\n } catch (error) {\n setNotice({ kind: 'error', text: messageOf(error) })\n return\n }\n void run(() => saveSettings(settings), '已保存,新的仓库会在后台拉取', true)\n }\n\n if (state === undefined || draft === undefined) {\n return (\n <div className=\"gx\">\n {loadError === undefined\n ? <div className=\"gx__loading\">加载中…</div>\n : <div className=\"gx__notice gx__notice--error\">{loadError} <button type=\"button\" className=\"gx__btn gx__btn--ghost\" onClick={() => { void reload(true) }}>重试</button></div>}\n </div>\n )\n }\n\n const available = state.repos.filter(repo => repo.available).length\n return (\n <div className=\"gx\">\n <header className=\"gx__head\">\n <div className=\"gx__headRow\">\n <h1 className=\"gx__title\">{PANEL_TITLE}</h1>\n <span className={`gx__pill ${available > 0 ? 'gx__pill--ok' : 'gx__pill--warn'}`}><span className=\"gx__dot\" />{available} 个应用可用</span>\n {syncing ? <span className=\"gx__pill gx__pill--warn\"><span className=\"gx__dot\" />拉取中</span> : null}\n </div>\n <div className=\"gx__meta\">观其象,知其因。在对话中输入 /guanxiang 描述问题并附上日志,观象会按应用派发分析。</div>\n <div className=\"gx__tabs\" role=\"tablist\">\n {TABS.map(item => (\n <button key={item.id} type=\"button\" role=\"tab\" className=\"gx__tab\" aria-selected={tab === item.id} onClick={() => { setTab(item.id) }}>{item.label}</button>\n ))}\n </div>\n </header>\n {state.overlayError === undefined ? null : <div className=\"gx__notice gx__notice--error\">面板设置文件未生效:{state.overlayError}。保存一次会用当前内容覆盖它。</div>}\n <div className=\"gx__body\" role=\"tabpanel\">\n {tab === 'repos' ? <ReposTab draft={draft} setDraft={setDraft} state={state} busy={busy || dirty} onSync={(url) => { void run(() => syncRepos(url), url === undefined ? '已开始重新拉取全部仓库' : '已开始重新拉取', false) }} /> : null}\n {tab === 'tokens'\n ? <TokensTab\n draft={draft}\n setDraft={setDraft}\n state={state}\n busy={busy}\n onAdd={async (credential, token) => {\n const saved = await run(() => saveSettings({ ...state.settings, gitCredentials: [...state.settings.gitCredentials, credential] }), token === '' ? `已添加 ${credential.url},请填入令牌` : `已添加 ${credential.url}`, false)\n const added = saved?.settings.gitCredentials[state.settings.gitCredentials.length]\n if (added === undefined) return false\n setDraft(current => current === undefined || current.gitCredentials.some(item => item.url === added.url) ? current : { ...current, gitCredentials: [...current.gitCredentials, added] })\n return token === '' || await run(() => saveToken(added.tokenEnv, token), `已添加 ${added.url} 并保存令牌,使用它的仓库会重新拉取`, false) !== undefined\n }}\n onSave={async (tokenEnv, value) => await run(() => saveToken(tokenEnv, value), `已保存 ${tokenEnv},使用它的仓库会重新拉取`, false) !== undefined}\n onClear={(tokenEnv) => { void run(() => clearToken(tokenEnv), `已清除面板保存的 ${tokenEnv}`, false) }}\n />\n : null}\n {tab === 'download' ? <DownloadTab draft={draft} setDraft={setDraft} overridden={state.overridden} /> : null}\n {tab === 'analyze'\n ? <AnalyzeTab\n draft={draft}\n setDraft={setDraft}\n analyze={state.analyze}\n credentialsAvailable={state.credentials.available}\n overridden={state.overridden}\n busy={busy}\n onSave={async value => await run(() => saveToken(state.analyze.tokenEnv, value), '已保存分析接口令牌,下一个请求起生效', false) !== undefined}\n onClear={() => { void run(() => clearToken(state.analyze.tokenEnv), '已清除面板保存的分析接口令牌', false) }}\n />\n : null}\n {tab === 'advanced' ? <AdvancedTab draft={draft} setDraft={setDraft} overridden={state.overridden} busy={busy} onReset={() => { void run(resetSettings, '已恢复为 cordis.yml 中的配置', true) }} /> : null}\n </div>\n {notice === undefined ? null : <div className={`gx__notice gx__notice--${notice.kind}`}>{notice.text}</div>}\n <div className=\"gx__saveBar\">\n <span className=\"gx__saveMsg\">{dirty ? '有未保存的修改' : '设置已保存'}</span>\n <button type=\"button\" className=\"gx__btn gx__btn--ghost\" disabled={!dirty || busy} onClick={() => { setDraft(toDraft(state.settings)); setNotice(undefined) }}>放弃修改</button>\n <button type=\"button\" className=\"gx__btn gx__btn--primary\" disabled={!dirty || busy} onClick={save}>保存</button>\n </div>\n </div>\n )\n}\n\ninterface TabProps {\n draft: Draft\n setDraft: (next: Draft) => void\n}\n\nfunction ReposTab({ draft, setDraft, state, busy, onSync }: TabProps & { state: StateWire; busy: boolean; onSync: (url?: string) => void }): JSX.Element {\n const [url, setUrl] = useState('')\n const [branch, setBranch] = useState('')\n const status = useMemo(() => new Map(state.repos.map(repo => [repo.url, repo])), [state.repos])\n const add = (): void => {\n const trimmed = url.trim()\n if (trimmed === '' || draft.repos.some(repo => repo.url === trimmed)) return\n setDraft({ ...draft, repos: [...draft.repos, branch.trim() === '' ? { url: trimmed } : { url: trimmed, branch: branch.trim() }] })\n setUrl('')\n setBranch('')\n }\n return (\n <section className=\"gx__sec\">\n <h2 className=\"gx__secTitle\">应用仓库 <Overridden keys={state.overridden} name=\"repos\" /></h2>\n <div className=\"gx__list\">\n {draft.repos.length === 0 ? <div className=\"gx__emptyRow\">还没有应用仓库。添加 git 地址后保存,观象会把仓库拉取到本机。</div> : null}\n {draft.repos.map((repo, index) => {\n const current = status.get(repo.url)\n const saved = current !== undefined && current.branch === repo.branch\n return (\n <div key={repo.url} className=\"gx__row gx__row--top\">\n <div className=\"gx__rowText\">\n <div className=\"gx__rowLabel\">\n <span className=\"gx__mono\">{repo.url}</span>\n {repo.branch === undefined ? null : <span className=\"gx__tag\">{repo.branch}</span>}\n {phasePill(saved ? current : undefined)}\n </div>\n {saved && current.app !== undefined\n ? <div className=\"gx__rowSummary\">{current.app.name}(<span className=\"gx__mono\">{current.app.id}</span>)· SKILL <span className=\"gx__mono\">/{current.app.skill}</span>{current.activeRuns > 0 ? ` · ${current.activeRuns} 个分析进行中` : ''}</div>\n : null}\n {saved && current.app !== undefined ? <div className=\"gx__rowSummary\">{current.app.description}</div> : null}\n {saved && current.commit !== undefined\n ? <div className=\"gx__rowSummary\">提交 <span className=\"gx__mono\">{current.commit.slice(0, 8)}</span>({formatTime(current.commitTime)})· 拉取于 {formatTime(current.syncedAt)} · <span className=\"gx__mono\">{current.dir}</span></div>\n : null}\n {saved && current.error !== undefined ? <div className=\"gx__rowError\">{current.error}</div> : null}\n </div>\n <div className=\"gx__rowCtl\">\n {saved ? <button type=\"button\" className=\"gx__btn\" disabled={busy || current.phase === 'syncing'} onClick={() => { onSync(repo.url) }}>重新拉取</button> : null}\n <button type=\"button\" className=\"gx__btn gx__btn--danger\" onClick={() => { setDraft({ ...draft, repos: draft.repos.filter((_, position) => position !== index) }) }}>删除</button>\n </div>\n </div>\n )\n })}\n <div className=\"gx__addRow\">\n <input className=\"gx__input\" placeholder=\"git 地址,例如 git@github.com:example/order-service.git\" value={url} onChange={(event) => { setUrl(event.target.value) }} onKeyDown={(event) => { if (event.key === 'Enter') add() }} />\n <input className=\"gx__input gx__input--branch\" placeholder=\"分支(可选)\" value={branch} onChange={(event) => { setBranch(event.target.value) }} onKeyDown={(event) => { if (event.key === 'Enter') add() }} />\n <button type=\"button\" className=\"gx__btn\" disabled={url.trim() === ''} onClick={add}>添加</button>\n </div>\n </div>\n <p className=\"gx__secFoot\">使用本机已有的 git 凭据(SSH key 或 credential helper)拉取;https 地址可在「访问令牌」中配置个人访问令牌。不留分支时跟随远端默认分支。每个仓库需包含 <span className=\"gx__mono\">.dsh/guanxiang.yaml</span> 与其中声明的日志分析 SKILL。删除地址不会删除本地目录。</p>\n {state.repos.length > 0 ? <div><button type=\"button\" className=\"gx__btn\" disabled={busy} onClick={() => { onSync() }}>重新拉取全部</button></div> : null}\n </section>\n )\n}\n\nconst DEFAULT_USERNAME = 'oauth2'\n/** Prefix of the credential keys the panel allocates; namespaced so an unrelated `GITLAB_TOKEN` in the environment is not picked up. */\nconst DEFAULT_TOKEN_ENV = 'GUANXIANG_GITLAB_TOKEN'\n\n/** Credential store layers of `@deepseek-ai/dsh-credentials-local` other than its own file. */\nconst TOKEN_SOURCES: Readonly<Record<string, string>> = { 'env': '启动环境变量', 'project-env': '项目 .env', 'user-env': '$DSH_HOME/.env' }\n\nfunction tokenPill(token: TokenStatusWire | undefined): JSX.Element {\n if (token === undefined) return <span className=\"gx__pill\"><span className=\"gx__dot\" />保存后设置令牌</span>\n if (token.error !== undefined) return <span className=\"gx__pill gx__pill--bad\"><span className=\"gx__dot\" />无法读取</span>\n if (!token.configured) return <span className=\"gx__pill gx__pill--warn\"><span className=\"gx__dot\" />未设置令牌</span>\n const source = token.source === undefined || token.source === 'file' ? undefined : TOKEN_SOURCES[token.source] ?? token.source\n return <span className=\"gx__pill gx__pill--ok\"><span className=\"gx__dot\" />已设置{source === undefined ? '' : `(来自${source})`}</span>\n}\n\n/**\n * First of `GUANXIANG_GITLAB_TOKEN`, `GUANXIANG_GITLAB_TOKEN_2`, … that no\n * saved or drafted entry uses.\n * @param used - keys already in use.\n * @returns a free key.\n */\nfunction freeTokenEnv(used: ReadonlySet<string>): string {\n if (!used.has(DEFAULT_TOKEN_ENV)) return DEFAULT_TOKEN_ENV\n let index = 2\n while (used.has(`${DEFAULT_TOKEN_ENV}_${index}`)) index += 1\n return `${DEFAULT_TOKEN_ENV}_${index}`\n}\n\nfunction TokensTab({ draft, setDraft, state, busy, onAdd, onSave, onClear }: TabProps & {\n state: StateWire\n busy: boolean\n /** Saves the entry, then its token; resolves whether both succeeded. */\n onAdd: (credential: GitCredentialSpec, token: string) => Promise<boolean>\n onSave: (tokenEnv: string, value: string) => Promise<boolean>\n onClear: (tokenEnv: string) => void\n}): JSX.Element {\n const [url, setUrl] = useState('')\n const [alias, setAlias] = useState('')\n const [token, setToken] = useState('')\n const [addError, setAddError] = useState<string | undefined>()\n // Spans both requests of one addition; `busy` drops between them.\n const [adding, setAdding] = useState(false)\n const [values, setValues] = useState<Record<string, string>>({})\n const tokens = useMemo(() => new Map(state.credentials.tokens.map(item => [item.tokenEnv, item])), [state.credentials.tokens])\n const saved = useMemo(() => new Set(state.settings.gitCredentials.map(credential => credential.tokenEnv)), [state.settings.gitCredentials])\n const complete = url.trim() !== '' && alias.trim() !== '' && token.trim() !== ''\n const add = (): void => {\n if (!complete || busy || adding) return\n const address = url.trim()\n if (state.settings.gitCredentials.some(credential => credential.url === address)) {\n setAddError('这个地址已经添加过了,请在上面的列表里更新它的令牌。')\n return\n }\n setAddError(undefined)\n setAdding(true)\n const tokenEnv = freeTokenEnv(new Set([...saved, ...draft.gitCredentials.map(credential => credential.tokenEnv)]))\n void onAdd({ url: address, alias: alias.trim(), username: DEFAULT_USERNAME, tokenEnv }, token.trim()).then((ok) => {\n if (!ok) return\n setUrl('')\n setAlias('')\n setToken('')\n }).finally(() => { setAdding(false) })\n }\n const save = (name: string): void => {\n const value = values[name]?.trim() ?? ''\n if (value === '' || busy || adding) return\n void onSave(name, value).then((ok) => { if (ok) setValues(current => ({ ...current, [name]: '' })) })\n }\n const submitOnEnter = (event: { key: string }): void => { if (event.key === 'Enter') add() }\n return (\n <section className=\"gx__sec\">\n <h2 className=\"gx__secTitle\">GitLab 访问令牌 <Overridden keys={state.overridden} name=\"gitCredentials\" /></h2>\n {state.credentials.available ? null : <div className=\"gx__notice gx__notice--error\">当前 DSH 组合没有加载凭据服务(@deepseek-ai/dsh-credentials-local),无法保存或读取令牌。</div>}\n <div className=\"gx__list\">\n {draft.gitCredentials.length === 0 ? <div className=\"gx__emptyRow\">还没有访问令牌。用 https 地址拉取 GitLab 私有仓库时,在下面填入 GitLab 地址、令牌别名和令牌。</div> : null}\n {draft.gitCredentials.map((credential, index) => {\n const status = saved.has(credential.tokenEnv) ? tokens.get(credential.tokenEnv) : undefined\n const value = values[credential.tokenEnv] ?? ''\n return (\n <div key={credential.url} className=\"gx__row gx__row--top\">\n <div className=\"gx__rowText\">\n <div className=\"gx__rowLabel\">\n <span>{credential.alias ?? credential.url}</span>\n {tokenPill(status)}\n </div>\n {credential.alias === undefined ? null : <div className=\"gx__rowSummary gx__mono\">{credential.url}</div>}\n {status?.error === undefined ? null : <div className=\"gx__rowError\">{status.error}</div>}\n {status !== undefined && status.writable\n ? (\n <div className=\"gx__addRow gx__addRow--flush\">\n <input className=\"gx__input gx__mono\" type=\"password\" autoComplete=\"new-password\" spellCheck={false} placeholder={status.configured ? '输入新令牌以替换' : '粘贴令牌'} value={value} onChange={(event) => { setValues({ ...values, [credential.tokenEnv]: event.target.value }) }} onKeyDown={(event) => { if (event.key === 'Enter') save(credential.tokenEnv) }} />\n <button type=\"button\" className=\"gx__btn\" disabled={busy || adding || value.trim() === ''} onClick={() => { save(credential.tokenEnv) }}>保存令牌</button>\n {status.configured && status.source === 'file' ? <button type=\"button\" className=\"gx__btn gx__btn--ghost\" disabled={busy} onClick={() => { onClear(credential.tokenEnv) }}>清除</button> : null}\n </div>\n )\n : null}\n </div>\n <div className=\"gx__rowCtl\">\n <button type=\"button\" className=\"gx__btn gx__btn--danger\" onClick={() => { setDraft({ ...draft, gitCredentials: draft.gitCredentials.filter((_, position) => position !== index) }) }}>删除</button>\n </div>\n </div>\n )\n })}\n <div className=\"gx__addForm\">\n <div className=\"gx__addRow gx__addRow--flush\">\n <label className=\"gx__field\">GitLab 地址<input className=\"gx__input\" placeholder=\"https://gitlab.example.com\" value={url} onChange={(event) => { setUrl(event.target.value) }} onKeyDown={submitOnEnter} /></label>\n <label className=\"gx__field\">令牌别名<input className=\"gx__input\" placeholder=\"例如 guanxiang\" value={alias} onChange={(event) => { setAlias(event.target.value) }} onKeyDown={submitOnEnter} /></label>\n <label className=\"gx__field\">令牌<input className=\"gx__input gx__mono\" type=\"password\" autoComplete=\"new-password\" spellCheck={false} placeholder=\"粘贴个人访问令牌\" value={token} onChange={(event) => { setToken(event.target.value) }} onKeyDown={submitOnEnter} /></label>\n <button type=\"button\" className=\"gx__btn gx__btn--end\" disabled={busy || adding || !complete} onClick={add}>添加</button>\n </div>\n {addError === undefined ? null : <div className=\"gx__rowError\">{addError}</div>}\n </div>\n </div>\n <p className=\"gx__secFoot\">地址在这个前缀下的 https 仓库使用对应令牌(多个匹配时取路径最长的),ssh 地址不受影响。拉取需要 read_repository 权限,开启 SKILL 改进时还需要 write_repository。令牌保存在 DSH 凭据库(默认 $DSH_HOME/.credentials.yaml,仅本机用户可读),面板只显示是否已设置;令牌只经环境变量交给 git,不写入设置文件、仓库配置、日志或模型上下文。</p>\n </section>\n )\n}\n\nfunction DownloadTab({ draft, setDraft, overridden }: TabProps & { overridden: readonly EditableKey[] }): JSX.Element {\n const [host, setHost] = useState('')\n const add = (): void => {\n const trimmed = host.trim().toLowerCase()\n if (trimmed === '' || draft.allowedHosts.includes(trimmed)) return\n setDraft({ ...draft, allowedHosts: [...draft.allowedHosts, trimmed] })\n setHost('')\n }\n return (\n <>\n <section className=\"gx__sec\">\n <h2 className=\"gx__secTitle\">允许下载的域名 <Overridden keys={overridden} name=\"download\" /></h2>\n <div className=\"gx__list\">\n {draft.allowedHosts.length === 0 ? <div className=\"gx__emptyRow\">未配置域名,消息中的日志下载链接不会被下载。</div> : null}\n {draft.allowedHosts.map(item => (\n <div key={item} className=\"gx__row\">\n <div className=\"gx__rowText\"><span className=\"gx__mono\">{item}</span></div>\n <div className=\"gx__rowCtl\"><button type=\"button\" className=\"gx__btn gx__btn--danger\" onClick={() => { setDraft({ ...draft, allowedHosts: draft.allowedHosts.filter(entry => entry !== item) }) }}>删除</button></div>\n </div>\n ))}\n <div className=\"gx__addRow\">\n <input className=\"gx__input\" placeholder=\"主机名,例如 oss.example.com\" value={host} onChange={(event) => { setHost(event.target.value) }} onKeyDown={(event) => { if (event.key === 'Enter') add() }} />\n <button type=\"button\" className=\"gx__btn\" disabled={host.trim() === ''} onClick={add}>添加</button>\n </div>\n </div>\n <p className=\"gx__secFoot\">只填主机名,同时允许它的子域名。下载不携带任何鉴权信息,每次重定向都会重新校验域名。</p>\n </section>\n <section className=\"gx__sec\">\n <h2 className=\"gx__secTitle\">限制</h2>\n <div className=\"gx__list\">\n <NumberRow label=\"单文件大小上限\" unit=\"MB\" value={draft.maxMb} onChange={(value) => { setDraft({ ...draft, maxMb: value }) }} />\n <NumberRow label=\"单文件下载超时\" unit=\"秒\" value={draft.timeoutSec} onChange={(value) => { setDraft({ ...draft, timeoutSec: value }) }} />\n </div>\n </section>\n </>\n )\n}\n\nconst TOPICS_STATUS: Readonly<Record<AnalyzeWire['topics'], { pill: string; text: string }>> = {\n ready: { pill: 'gx__pill--ok', text: '飞书渠道就绪' },\n missing: { pill: 'gx__pill--bad', text: '未找到飞书渠道' },\n incompatible: { pill: 'gx__pill--bad', text: '飞书渠道版本不兼容' },\n}\n\nfunction AnalyzeTab({ draft, setDraft, analyze, credentialsAvailable, overridden, busy, onSave, onClear }: TabProps & {\n analyze: AnalyzeWire\n credentialsAvailable: boolean\n overridden: readonly EditableKey[]\n busy: boolean\n onSave: (value: string) => Promise<boolean>\n onClear: () => void\n}): JSX.Element {\n const [value, setValue] = useState('')\n const token = analyze.token\n const save = (): void => {\n const trimmed = value.trim()\n if (trimmed === '' || busy) return\n void onSave(trimmed).then((ok) => { if (ok) setValue('') })\n }\n const topics = TOPICS_STATUS[analyze.topics]\n const endpoint = new URL(analyze.route.slice(1), document.baseURI).href\n return (\n <>\n <section className=\"gx__sec\">\n <h2 className=\"gx__secTitle\">日志平台分析接口</h2>\n <div className=\"gx__list\">\n <div className=\"gx__row\">\n <div className=\"gx__rowText\">\n <div className=\"gx__rowLabel\">开启接口 <Overridden keys={overridden} name=\"analyze\" /><span className={`gx__pill ${topics.pill}`}><span className=\"gx__dot\" />{topics.text}</span></div>\n <div className=\"gx__rowSummary\">日志平台调用接口后,观象经飞书渠道(dsh-channels 0.8 及以上)在目标群发出分析卡片,并在卡片下的话题里开始分析;群内成员都可以在话题里继续追问。关闭时接口回复 404。</div>\n {analyze.topics === 'ready' ? null : <div className=\"gx__rowError\">{analyze.topics === 'missing' ? '接口需要 dsh-channels 0.8 及以上版本并已加载;dsh-channels 0.7 自带同名接口,升级前由它提供。' : '请把观象与 dsh-channels 升级到相互兼容的版本。'}</div>}\n </div>\n <div className=\"gx__rowCtl\"><input type=\"checkbox\" className=\"gx__check\" aria-label=\"开启分析接口\" checked={draft.analyzeEnabled} onChange={(event) => { setDraft({ ...draft, analyzeEnabled: event.target.checked }) }} /></div>\n </div>\n <div className=\"gx__row gx__row--top\">\n <div className=\"gx__rowText\">\n <div className=\"gx__rowLabel\">访问令牌 <span className=\"gx__tag gx__mono\">{analyze.tokenEnv}</span>{credentialsAvailable ? tokenPill(token) : null}</div>\n <div className=\"gx__rowSummary\">日志平台以 <span className=\"gx__mono\">Authorization: Bearer <令牌></span> 调用接口。令牌未设置时接口回复 503。</div>\n {credentialsAvailable ? null : <div className=\"gx__rowError\">当前 DSH 组合没有加载凭据服务(@deepseek-ai/dsh-credentials-local),无法保存或读取令牌。</div>}\n {token?.error === undefined ? null : <div className=\"gx__rowError\">{token.error}</div>}\n {token !== undefined && token.writable\n ? (\n <div className=\"gx__addRow gx__addRow--flush\">\n <input className=\"gx__input gx__mono\" type=\"password\" autoComplete=\"new-password\" spellCheck={false} placeholder={token.configured ? '输入新令牌以替换' : '粘贴令牌'} value={value} onChange={(event) => { setValue(event.target.value) }} onKeyDown={(event) => { if (event.key === 'Enter') save() }} />\n <button type=\"button\" className=\"gx__btn\" disabled={busy || value.trim() === ''} onClick={save}>保存令牌</button>\n {token.configured && token.source === 'file' ? <button type=\"button\" className=\"gx__btn gx__btn--ghost\" disabled={busy} onClick={onClear}>清除</button> : null}\n </div>\n )\n : null}\n </div>\n </div>\n </div>\n </section>\n <section className=\"gx__sec\">\n <h2 className=\"gx__secTitle\">调用方式</h2>\n <div className=\"gx__list\">\n <div className=\"gx__row\"><div className=\"gx__rowText\"><div className=\"gx__rowLabel\">地址</div><div className=\"gx__rowSummary gx__mono\">POST {endpoint}</div></div></div>\n <div className=\"gx__row\"><div className=\"gx__rowText\"><div className=\"gx__rowLabel\">请求头</div><div className=\"gx__rowSummary gx__mono\">Authorization: Bearer <令牌> · Idempotency-Key: <1-200 个可见 ASCII 字符> · Content-Type: application/json</div></div></div>\n <div className=\"gx__row\"><div className=\"gx__rowText\"><div className=\"gx__rowLabel\">请求体</div><div className=\"gx__rowSummary gx__mono\">requesterUserId, triggeredAt, app, errorCode, logDetails[{'{'}name, url{'}'}], chatId, prompt</div></div></div>\n <div className=\"gx__row\"><div className=\"gx__rowText\"><div className=\"gx__rowLabel\">响应</div><div className=\"gx__rowSummary\">202 已发出分析卡片(同一 Idempotency-Key 重试返回同一张卡片);400/401/404/405/409/413/415 请求问题;403 目标群未授权;502 卡片发送失败;503 飞书未连接或令牌未设置。字段说明见观象 README。</div></div></div>\n </div>\n </section>\n </>\n )\n}\n\nfunction AdvancedTab({ draft, setDraft, overridden, busy, onReset }: TabProps & { overridden: readonly EditableKey[]; busy: boolean; onReset: () => void }): JSX.Element {\n return (\n <>\n <section className=\"gx__sec\">\n <h2 className=\"gx__secTitle\">仓库</h2>\n <div className=\"gx__list\">\n <div className=\"gx__row\">\n <div className=\"gx__rowText\">\n <div className=\"gx__rowLabel\">拉取目录 <Overridden keys={overridden} name=\"reposDir\" /></div>\n <div className=\"gx__rowSummary\">每个仓库拉取到该目录下的同名子目录,观象只读使用。</div>\n </div>\n <div className=\"gx__rowCtl\"><input className=\"gx__input gx__input--wide gx__mono\" value={draft.reposDir} onChange={(event) => { setDraft({ ...draft, reposDir: event.target.value }) }} /></div>\n </div>\n <NumberRow label=\"更新间隔\" summary=\"输入 /guanxiang 时,距上次拉取超过该时间的仓库会先更新;0 表示每次都更新。\" unit=\"分钟\" value={draft.fetchIntervalMin} overridden={overridden.includes('fetchIntervalMs')} onChange={(value) => { setDraft({ ...draft, fetchIntervalMin: value }) }} />\n </div>\n </section>\n <section className=\"gx__sec\">\n <h2 className=\"gx__secTitle\">派发</h2>\n <div className=\"gx__list\">\n <NumberRow label=\"单次应用数上限\" summary=\"一次派发最多同时分析的应用数,不应超过 DSH 的活动子 Agent 上限(默认 8)。\" unit=\"个\" value={draft.maxAppsPerRequest} overridden={overridden.includes('maxAppsPerRequest')} onChange={(value) => { setDraft({ ...draft, maxAppsPerRequest: value }) }} />\n <NumberRow label=\"派发超时\" summary=\"等待全部子 Agent 的最长时间,超时后停止仍在运行的子 Agent。\" unit=\"分钟\" value={draft.dispatchTimeoutMin} overridden={overridden.includes('dispatchTimeoutMs')} onChange={(value) => { setDraft({ ...draft, dispatchTimeoutMin: value }) }} />\n </div>\n </section>\n <section className=\"gx__sec\">\n <h2 className=\"gx__secTitle\">SKILL 改进</h2>\n <div className=\"gx__list\">\n <div className=\"gx__row\">\n <div className=\"gx__rowText\">\n <div className=\"gx__rowLabel\">允许提出 SKILL 修改 <Overridden keys={overridden} name=\"skillUpdates\" /></div>\n <div className=\"gx__rowSummary\">子 Agent 发现应用的日志分析 SKILL 有欠缺时可以写出修改提议;经用户授权后,观象用访问令牌把它推送到新分支并创建合并请求(GitLab,令牌需要 write_repository 权限)。</div>\n </div>\n <div className=\"gx__rowCtl\"><input type=\"checkbox\" className=\"gx__check\" aria-label=\"允许提出 SKILL 修改\" checked={draft.skillUpdatesEnabled} onChange={(event) => { setDraft({ ...draft, skillUpdatesEnabled: event.target.checked }) }} /></div>\n </div>\n <NumberRow label=\"提议文件数上限\" unit=\"个\" value={draft.skillMaxFiles} onChange={(value) => { setDraft({ ...draft, skillMaxFiles: value }) }} />\n <NumberRow label=\"提议单文件大小上限\" unit=\"KB\" value={draft.skillMaxKb} onChange={(value) => { setDraft({ ...draft, skillMaxKb: value }) }} />\n </div>\n </section>\n <section className=\"gx__sec\">\n <h2 className=\"gx__secTitle\">面板设置</h2>\n <div className=\"gx__list\">\n <div className=\"gx__row\">\n <div className=\"gx__rowText\">\n <div className=\"gx__rowLabel\">恢复 cordis.yml 配置</div>\n <div className=\"gx__rowSummary\">删除面板保存的全部设置($DSH_HOME/guanxiang/settings.json 中的覆盖值)。</div>\n </div>\n <div className=\"gx__rowCtl\"><button type=\"button\" className=\"gx__btn gx__btn--danger\" disabled={busy || overridden.length === 0} onClick={onReset}>恢复</button></div>\n </div>\n </div>\n </section>\n </>\n )\n}\n\nfunction NumberRow({ label, summary, unit, value, overridden = false, onChange }: { label: string; summary?: string; unit: string; value: string; overridden?: boolean; onChange: (value: string) => void }): JSX.Element {\n return (\n <div className=\"gx__row\">\n <div className=\"gx__rowText\">\n <div className=\"gx__rowLabel\">{label}{overridden ? <span className=\"gx__tag gx__tag--accent\">面板设置</span> : null}</div>\n {summary === undefined ? null : <div className=\"gx__rowSummary\">{summary}</div>}\n </div>\n <div className=\"gx__rowCtl\">\n <input className=\"gx__input gx__input--num\" inputMode=\"decimal\" value={value} onChange={(event) => { onChange(event.target.value) }} />\n <span className=\"gx__unit\">{unit}</span>\n </div>\n </div>\n )\n}\n","/**\n * 「观象」页面样式。使用 DSH 语义 token(`--dsw-alias-*`)并带中性回退,\n * 页面随当前主题变化。\n *\n * @module dsh-guanxiang/client/styles\n */\n\nconst STYLE_ATTRIBUTE = 'data-dsh-guanxiang-css'\n\nconst CSS = `\n.gx-page{width:100%;height:100%;min-width:0;min-height:0;overflow:auto;scrollbar-gutter:stable;background:var(--dsw-alias-bg-base,#fff)}\n.gx-page__content{box-sizing:border-box;max-width:816px;margin:0 auto;padding:18px clamp(24px,4vw,48px) 48px}\n[data-platform='darwin'] .gx-page__content{padding-top:calc(18px + var(--dsh-frame-top-clearance,0px))}\n.gx{--gx-fg:var(--dsw-alias-label-primary,#1f2328);--gx-fg2:var(--dsw-alias-label-secondary,#5c6169);--gx-fg3:var(--dsw-alias-label-tertiary,#8a8f98);--gx-dim:var(--dsw-alias-label-dimmed,#b0b4ba);--gx-bg:var(--dsw-alias-bg-base,#fff);--gx-line:var(--dsw-alias-border-l2,rgba(0,0,0,.12));--gx-hover:var(--dsw-alias-interactive-bg-hover,rgba(0,0,0,.05));--gx-accent:var(--dsw-alias-state-business-primary,#0a67d3);--gx-ok:var(--dsw-alias-state-success-primary,#0a7d33);--gx-warn:var(--dsw-alias-state-warn-primary,#a15c00);--gx-bad:var(--dsw-alias-state-error-primary,#c62828);--gx-mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;display:flex;flex-direction:column;gap:14px;width:100%;max-width:720px;color:var(--gx-fg);font-size:13px;line-height:20px}\n.gx__head{position:sticky;top:0;z-index:2;display:flex;flex-direction:column;gap:4px;padding:10px 0 6px;background:var(--gx-bg)}\n.gx__headRow{display:flex;align-items:center;gap:8px;flex-wrap:wrap}\n.gx__title{margin:0 2px 0 0;font-size:20px;font-weight:500;line-height:28px}\n.gx__meta{color:var(--gx-fg3);font-size:12px}\n.gx__mono{font-family:var(--gx-mono);font-size:12px}\n.gx__pill{display:inline-flex;align-items:center;gap:5px;padding:0 8px;border-radius:999px;font-size:12px;line-height:20px;white-space:nowrap;color:var(--gx-fg3);background:color-mix(in srgb,currentColor 10%,transparent)}\n.gx__pill--ok{color:var(--gx-ok)}\n.gx__pill--warn{color:var(--gx-warn)}\n.gx__pill--bad{color:var(--gx-bad)}\n.gx__dot{width:6px;height:6px;border-radius:50%;background:currentColor;flex:none}\n.gx__tabs{display:flex;align-items:center;gap:18px;border-bottom:1px solid var(--gx-line);overflow-x:auto;scrollbar-width:none}\n.gx__tab{display:inline-flex;align-items:center;min-height:34px;padding:0;border:0;border-bottom:2px solid transparent;background:transparent;color:var(--gx-fg2);font:inherit;font-size:13px;cursor:pointer;white-space:nowrap}\n.gx__tab:hover{color:var(--gx-fg)}\n.gx__tab[aria-selected=\"true\"]{color:var(--gx-fg);border-bottom-color:currentColor;font-weight:600}\n.gx__body{display:flex;flex-direction:column;gap:22px;padding:4px 0 8px}\n.gx__sec{display:flex;flex-direction:column;gap:6px;margin:0}\n.gx__secTitle{margin:0;font-size:12px;font-weight:600;line-height:18px;color:var(--gx-fg3);letter-spacing:.02em}\n.gx__secFoot{margin:0;color:var(--gx-fg3);font-size:12px;line-height:18px}\n.gx__list{display:flex;flex-direction:column;border:1px solid var(--gx-line);border-radius:10px}\n.gx__list>*+*{border-top:1px solid var(--gx-line)}\n.gx__row{display:flex;align-items:center;gap:16px;padding:11px 14px;min-height:28px}\n.gx__row--top{align-items:flex-start}\n.gx__rowText{display:flex;flex-direction:column;gap:2px;flex:1 1 auto;min-width:0}\n.gx__rowLabel{display:flex;align-items:center;gap:6px;flex-wrap:wrap;overflow-wrap:anywhere}\n.gx__rowSummary{color:var(--gx-fg3);font-size:12px;line-height:18px;overflow-wrap:anywhere}\n.gx__rowError{color:var(--gx-bad);font-size:12px;line-height:18px;overflow-wrap:anywhere;white-space:pre-wrap}\n.gx__rowCtl{flex:none;display:flex;align-items:center;gap:6px;justify-content:flex-end}\n.gx__tag{display:inline-flex;align-items:center;padding:0 5px;border-radius:4px;font-size:11px;line-height:16px;white-space:nowrap;color:var(--gx-fg2);background:var(--gx-hover)}\n.gx__tag--accent{color:var(--gx-accent);background:color-mix(in srgb,var(--gx-accent) 10%,transparent)}\n.gx__input{box-sizing:border-box;width:100%;min-width:0;height:30px;padding:0 10px;border:1px solid var(--gx-line);border-radius:7px;background:var(--dsw-alias-bg-layer-1,transparent);color:inherit;font:inherit;font-size:13px;outline:none}\n.gx__input:focus{border-color:var(--gx-accent)}\n.gx__input--num{width:120px;text-align:right;font-variant-numeric:tabular-nums}\n.gx__input--wide{width:320px}\n.gx__check{width:16px;height:16px;margin:0;accent-color:var(--gx-accent);cursor:pointer}\n.gx__unit{min-width:36px;color:var(--gx-fg3);font-size:12px}\n.gx__addRow{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:10px 14px}\n.gx__addRow .gx__input{flex:1 1 160px;width:auto}\n.gx__addRow .gx__input--branch{flex:0 1 140px}\n.gx__addRow--flush{padding:6px 0 0}\n.gx__addForm{display:flex;flex-direction:column;gap:6px;padding:10px 14px}\n.gx__field{display:flex;flex-direction:column;gap:2px;flex:1 1 160px;color:var(--gx-fg3);font-size:12px}\n.gx__field .gx__input{flex:none;width:100%}\n.gx__btn--end{align-self:flex-end;height:30px}\n.gx__emptyRow{padding:11px 14px;color:var(--gx-fg3);font-size:12px}\n.gx__btn{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;gap:4px;height:28px;padding:0 12px;border:1px solid var(--gx-line);border-radius:7px;background:transparent;color:inherit;font:inherit;font-size:13px;cursor:pointer;white-space:nowrap}\n.gx__btn:hover:not(:disabled){background:var(--gx-hover)}\n.gx__btn:disabled{color:var(--gx-dim);cursor:default}\n.gx__btn--primary{background:var(--dsw-alias-button-primary-fill,var(--gx-accent));border-color:transparent;color:var(--dsw-alias-label-primary-foreground,#fff)}\n.gx__btn--primary:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover,#0b5cba)}\n.gx__btn--primary:disabled{opacity:.45;color:var(--dsw-alias-label-primary-foreground,#fff)}\n.gx__btn--ghost{border-color:transparent;color:var(--gx-fg2)}\n.gx__btn--danger{color:var(--gx-bad)}\n.gx__btn:focus-visible,.gx__tab:focus-visible{outline:2px solid var(--gx-accent);outline-offset:2px}\n.gx__notice{padding:8px 12px;border-radius:8px;font-size:12px;line-height:18px;overflow-wrap:anywhere}\n.gx__notice--ok{color:var(--gx-ok);background:color-mix(in srgb,var(--gx-ok) 9%,transparent)}\n.gx__notice--error{color:var(--gx-bad);background:color-mix(in srgb,var(--gx-bad) 8%,transparent)}\n.gx__saveBar{position:sticky;bottom:0;z-index:2;display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:10px 0;border-top:1px solid var(--gx-line);background:var(--gx-bg)}\n.gx__saveMsg{flex:1;min-width:0;color:var(--gx-fg2);font-size:12px}\n.gx__loading{padding:16px 0;color:var(--gx-fg3);font-size:12px}\n`\n\n/**\n * Install the page stylesheet once.\n * @returns disposer removing it.\n */\nexport function installStyles(): () => void {\n const existing = document.querySelector(`style[${STYLE_ATTRIBUTE}]`)\n if (existing !== null) return () => {}\n const element = document.createElement('style')\n element.setAttribute(STYLE_ATTRIBUTE, '')\n element.textContent = CSS\n document.head.append(element)\n return () => { element.remove() }\n}\n","/**\n * 观象 client half:左侧栏全局入口「观象」+ 主区整页设置面板。\n *\n * 只依赖平台核心的 `slots` 服务与 react(bundle 里 react 走平台模块表,\n * 其余全部内联);页面数据来自 Host 半侧的 `/guanxiang/*` 路由。\n *\n * @module dsh-guanxiang/client\n */\n\nimport { GuanxiangIcon } from './icon.tsx'\nimport { GuanxiangPage, PANEL_TITLE } from './page.tsx'\nimport { installStyles } from './styles.ts'\n\n/** Slots runtime surface this bundle uses: list slots by `id`, keyed slots by `key`. */\nexport interface ClientSlots {\n inject(slot: string, contribution: () => unknown): void\n register(\n declaration:\n | { name: string; id: string; order?: number; label?: () => string }\n | { name: string; key: string },\n component: (props: never) => unknown,\n ): () => void\n}\n\n/** Client plugin context. */\nexport interface ClientContext {\n slots: ClientSlots\n effect?(callback: () => void | (() => void), label?: string): void\n}\n\n/** Cordis client plugin name. */\nexport const name = 'dsh-guanxiang'\n\n/** Required client services: the Slots registry is part of the web shell core. */\nexport const inject = ['slots']\n\n/**\n * Main panel id: the `sidebar.panellist` row id and the matching `main` slot\n * key. Must not change once released: DSH keys navigation state by it.\n */\nexport const PANEL_ID = 'guanxiang'\n/** Left-sidebar row order (dsh-channels uses 40). */\nexport const PANEL_ORDER = 45\n\n/**\n * Mount the left-sidebar entry, its main-column page, and the stylesheet.\n * @param ctx - client plugin context carrying the slots registry.\n */\nexport function apply(ctx: ClientContext): void {\n if (typeof ctx.effect === 'function') ctx.effect(() => installStyles(), 'dsh-guanxiang: panel styles')\n else installStyles()\n ctx.slots.inject('main', () => ctx.slots.register({ name: 'main', key: PANEL_ID }, GuanxiangPage))\n ctx.slots.inject('sidebar.panellist', () => ctx.slots.register({\n name: 'sidebar.panellist',\n id: PANEL_ID,\n order: PANEL_ORDER,\n label: () => PANEL_TITLE,\n }, GuanxiangIcon))\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","names":[],"sources":["../src/client/icon.tsx","../src/settings/contract.ts","../src/client/api.ts","../src/client/page.tsx","../src/client/styles.ts","../src/client/index.ts"],"sourcesContent":["/**\n * 左侧栏「观象」行的装饰图标;行本身负责可访问名称(列表注册的 label)。\n *\n * @module dsh-guanxiang/client/icon\n */\n\n/** Owner share of `sidebar.panellist`: requested square edge and selection state. */\nexport interface GuanxiangIconProps {\n size: number\n active: boolean\n}\n\n/**\n * Eye-over-waveform glyph drawn in `currentColor`.\n * @param props - the sidebar's icon share.\n * @returns decorative icon.\n */\nexport function GuanxiangIcon({ size }: GuanxiangIconProps): JSX.Element {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={1.6} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M2.5 10c2.4-3.6 5.6-5.4 9.5-5.4s7.1 1.8 9.5 5.4c-2.4 3.6-5.6 5.4-9.5 5.4S4.9 13.6 2.5 10Z\" />\n <circle cx=\"12\" cy=\"10\" r=\"2.4\" />\n <path d=\"M3 19.5h3l2-2.5 2.5 4 3-6 2.5 4.5 1.5-2h3.5\" />\n </svg>\n )\n}\n","/**\n * 设置面板与 Host 路由共用的路由常量和 JSON 结构。浏览器端 bundle 也会\n * 编译本文件,因此这里只放类型和常量,不 import 任何 Node 模块。\n *\n * @module dsh-guanxiang/settings/contract\n */\n\n/** GET:面板所需的全部状态(生效设置、默认值、仓库与应用)。 */\nexport const STATE_ROUTE = '/guanxiang/state'\n/** PUT:保存可编辑设置;DELETE:清除面板覆盖、恢复 cordis.yml 默认值。 */\nexport const SETTINGS_ROUTE = '/guanxiang/settings'\n/** POST:立即重新拉取全部仓库,或 body `{ url }` 指定的一个仓库。 */\nexport const SYNC_ROUTE = '/guanxiang/sync'\n/** PUT:body `{ tokenEnv, value }` 把令牌存入 DSH 凭据库;DELETE:body `{ tokenEnv }` 删除已存的值。只接受已保存的访问令牌配置引用的名称和分析接口令牌的名称。 */\nexport const TOKEN_ROUTE = '/guanxiang/token'\n\n/**\n * POST:日志平台分析接口(Bearer 令牌鉴权,不走 DSH 登录)。它在 DSH 的\n * `/api` 命名空间之外,网关可以把它和需要登录的 DSH 接口分开暴露。\n */\nexport const ANALYZE_ROUTE = '/open-api/logalyze'\n\n/** One configured application repository. */\nexport interface RepoSpec {\n /** Git remote address, cloned with the host machine's existing git credentials or a matching {@link GitCredentialSpec}. */\n url: string\n /** Remote branch to follow; omitted follows the remote's default branch. */\n branch?: string\n}\n\n/** Credential reference grammar of `@deepseek-ai/dsh-credentials` (a POSIX shell identifier), which {@link GitCredentialSpec.tokenEnv} follows. */\nexport const TOKEN_ENV_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/\n\n/** HTTPS access token used for the repositories under one address prefix. */\nexport interface GitCredentialSpec {\n /** `https://host[:port][/path]` (or `http://`) prefix; repository addresses under it use this token. */\n url: string\n /** Display name the panel shows for this token; omitted shows the address. */\n alias?: string\n /** HTTP username sent with the token; GitLab personal access tokens accept `oauth2`. */\n username: string\n /** Credential reference (environment-variable name) whose value in DSH's credential store is the token. */\n tokenEnv: string\n}\n\n/** Log URL download policy. */\nexport interface DownloadSettings {\n /** Allowed host names; `example.com` also admits its subdomains. Empty disables URL downloads. */\n allowedHosts: string[]\n /** Per-file byte ceiling. */\n maxBytes: number\n /** Per-file download timeout in milliseconds. */\n timeoutMs: number\n}\n\n/** Application SKILL improvement proposals that children may write and the top-level agent may submit as merge requests. */\nexport interface SkillUpdateSettings {\n /** Whether children are told how to propose SKILL changes and top-level agents are offered `guanxiang_propose_skill`. */\n enabled: boolean\n /** Most files one proposal may add or change. */\n maxFiles: number\n /** Largest proposed file, in bytes. */\n maxFileBytes: number\n}\n\n/** The log-platform analyze API ({@link ANALYZE_ROUTE}). */\nexport interface AnalyzeSettings {\n /** Whether the API accepts requests; switched off it answers 404. */\n enabled: boolean\n}\n\n/** The settings the Web panel can override; every field is required on the wire. */\nexport interface EditableSettings {\n /** Absolute directory holding the cloned repositories (`~` expands to the home directory). */\n reposDir: string\n /** Application repositories to clone and keep updated. */\n repos: RepoSpec[]\n /** HTTPS access tokens by address prefix; the token values stay in DSH's credential store. */\n gitCredentials: GitCredentialSpec[]\n /** Minimum age of a repository's last sync before loading `/guanxiang` syncs it again, in milliseconds; 0 syncs on every load. */\n fetchIntervalMs: number\n /** Maximum number of child analyses one dispatch may start. */\n maxAppsPerRequest: number\n /** Whole-dispatch wait budget in milliseconds; children still running then are stopped. */\n dispatchTimeoutMs: number\n /** URL download policy. */\n download: DownloadSettings\n /** SKILL improvement proposals. */\n skillUpdates: SkillUpdateSettings\n /** Log-platform analyze API. */\n analyze: AnalyzeSettings\n}\n\n/** Keys of {@link EditableSettings}, in panel order. */\nexport const EDITABLE_KEYS = ['reposDir', 'repos', 'gitCredentials', 'fetchIntervalMs', 'maxAppsPerRequest', 'dispatchTimeoutMs', 'download', 'skillUpdates', 'analyze'] as const satisfies readonly (keyof EditableSettings)[]\n\n/** One editable key. */\nexport type EditableKey = (typeof EDITABLE_KEYS)[number]\n\n/** Application description read from `<repo>/.dsh/guanxiang.yaml`. */\nexport interface AppManifest {\n /** Registry id the dispatch tool and analysis requests address. */\n id: string\n /** Display name, also the child agent's label. */\n name: string\n /** What the application does, used for intent recognition. */\n description: string\n /** Other names users call the application by. */\n aliases: string[]\n /** Strings that identify this application's log lines (tags, process names, class names). */\n logHints: string[]\n /** Project skill name under `.dsh/skills/<skill>/SKILL.md` that analyzes this application's logs. */\n skill: string\n}\n\n/** Lifecycle of one repository checkout. */\nexport type RepoPhase = 'pending' | 'syncing' | 'ready' | 'failed'\n\n/** One repository as the panel shows it. */\nexport interface RepoStatusWire {\n url: string\n branch?: string\n /** Absolute directory of the fetch-only clone; children work in commit snapshots under `<reposDir>/.snapshots/`. */\n dir: string\n phase: RepoPhase\n /** Latest synced commit, the one the catalog describes and new dispatches use. */\n commit?: string\n /** Committer date of {@link commit}, ISO 8601. */\n commitTime?: string\n /** Last completed sync attempt, epoch milliseconds. */\n syncedAt?: number\n /** Application description read from {@link commit}. */\n app?: AppManifest\n /** Why the repository is unusable (`failed`), or why the last update failed while an older commit stays usable (`ready`). */\n error?: string\n /** Whether the application is offered to intent recognition and dispatch. */\n available: boolean\n /** Child analyses currently running in snapshots of this repository. */\n activeRuns: number\n}\n\n/** Whether one referenced token has a value — never the value. */\nexport interface TokenStatusWire {\n tokenEnv: string\n /** Whether resolving the reference currently returns a value. */\n configured: boolean\n /** Credential store layer supplying the value (`file`, `env`, `project-env`, `user-env`); absent while unconfigured. */\n source?: string\n /** Whether the panel can store a value for this reference. */\n writable: boolean\n /** Why the credential store could not describe the reference. */\n error?: string\n}\n\n/** Credential store view of the panel. */\nexport interface CredentialsWire {\n /** Whether the DSH composition provides `ctx.credentials`; without it tokens cannot be stored or read. */\n available: boolean\n /** One entry per distinct `tokenEnv` of the effective settings; empty while unavailable. */\n tokens: TokenStatusWire[]\n}\n\n/**\n * Whether dsh-channels provides the `feishuTopics` service the analyze API\n * posts through: `missing` while it is not loaded (or older than 0.8, which\n * serves the API itself), `incompatible` when its contract version is not\n * the one this plugin speaks.\n */\nexport type TopicsAvailability = 'ready' | 'missing' | 'incompatible'\n\n/** Analyze API view of the panel. */\nexport interface AnalyzeWire {\n /** Route the log platform posts to. */\n route: string\n /** Credential reference (`analyzeTokenRef`) holding the bearer token. */\n tokenEnv: string\n /** Token status; absent while the DSH composition has no credential store. */\n token?: TokenStatusWire\n topics: TopicsAvailability\n}\n\n/** `GET /guanxiang/state` response. */\nexport interface StateWire {\n /** Effective settings: cordis.yml values with panel overrides applied. */\n settings: EditableSettings\n /** cordis.yml values before panel overrides. */\n defaults: EditableSettings\n /** Keys the panel currently overrides. */\n overridden: EditableKey[]\n /** Why the overlay file was ignored (unreadable or invalid); panel saves replace it. */\n overlayError?: string\n repos: RepoStatusWire[]\n credentials: CredentialsWire\n analyze: AnalyzeWire\n}\n\n/** Successful mutation response. */\nexport interface MutationOk {\n ok: true\n state: StateWire\n}\n\n/** Failed request response. */\nexport interface MutationError {\n ok: false\n error: string\n}\n","/**\n * 设置面板的同源 HTTP 客户端,直接请求 Host 半侧注册的 `/guanxiang/*` 路由。\n *\n * @module dsh-guanxiang/client/api\n */\n\nimport { SETTINGS_ROUTE, STATE_ROUTE, SYNC_ROUTE, TOKEN_ROUTE } from '../settings/contract.ts'\nimport type { EditableSettings, MutationError, MutationOk, StateWire } from '../settings/contract.ts'\n\n/**\n * Error text of a value thrown by a request.\n * @param error - thrown value.\n * @returns message.\n */\nexport function messageOf(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n\n/**\n * Fetch one Host route. Routes are absolute pathnames, but the browser\n * addresses them relative to the DSH document so a reverse proxy that mounts\n * DSH under a prefix still routes them with its scoped login cookie.\n */\nasync function request<T>(route: string, init?: RequestInit): Promise<T> {\n let response: Response\n try {\n response = await fetch(route.slice(1), {\n cache: 'no-store',\n credentials: 'same-origin',\n ...init,\n headers: { accept: 'application/json', ...init?.body === undefined ? {} : { 'content-type': 'application/json' } },\n })\n } catch (error) {\n throw new Error(`无法连接设置接口:${messageOf(error)}`)\n }\n const text = await response.text()\n let body: unknown\n try {\n body = JSON.parse(text)\n } catch {\n // Non-JSON bodies (proxy errors) are reported by HTTP status below.\n throw new Error(`HTTP ${response.status}`)\n }\n if (!response.ok) {\n const error = (body as Partial<MutationError>).error\n throw new Error(typeof error === 'string' && error !== '' ? error : `HTTP ${response.status}`)\n }\n return body as T\n}\n\n/** @returns the panel state. */\nexport function fetchState(): Promise<StateWire> {\n return request<StateWire>(STATE_ROUTE)\n}\n\n/**\n * Save the complete editable settings.\n * @param settings - settings to persist.\n * @returns the new state.\n */\nexport async function saveSettings(settings: EditableSettings): Promise<StateWire> {\n return (await request<MutationOk>(SETTINGS_ROUTE, { method: 'PUT', body: JSON.stringify(settings) })).state\n}\n\n/** @returns the state after removing every panel override. */\nexport async function resetSettings(): Promise<StateWire> {\n return (await request<MutationOk>(SETTINGS_ROUTE, { method: 'DELETE' })).state\n}\n\n/**\n * Re-sync one repository or all of them.\n * @param url - repository address; omitted syncs all.\n * @returns the state right after the sync started.\n */\nexport async function syncRepos(url?: string): Promise<StateWire> {\n return (await request<MutationOk>(SYNC_ROUTE, { method: 'POST', body: JSON.stringify(url === undefined ? {} : { url }) })).state\n}\n\n/**\n * Store an access token in DSH's credential store.\n * @param tokenEnv - credential reference named by a saved access-token configuration.\n * @param value - token value.\n * @returns the new state, which reports only whether the token is set.\n */\nexport async function saveToken(tokenEnv: string, value: string): Promise<StateWire> {\n return (await request<MutationOk>(TOKEN_ROUTE, { method: 'PUT', body: JSON.stringify({ tokenEnv, value }) })).state\n}\n\n/**\n * Remove a stored access token.\n * @param tokenEnv - credential reference named by a saved access-token configuration.\n * @returns the new state.\n */\nexport async function clearToken(tokenEnv: string): Promise<StateWire> {\n return (await request<MutationOk>(TOKEN_ROUTE, { method: 'DELETE', body: JSON.stringify({ tokenEnv }) })).state\n}\n","/**\n * 左侧栏「观象」主区页面:应用仓库、访问令牌、日志下载、分析接口、高级(含 SKILL 改进)五个\n * 分页,共用一份草稿和底部保存条;令牌值不进草稿,单独存入 DSH 凭据库。\n * 仓库拉取中时每 2 秒刷新状态。\n *\n * @module dsh-guanxiang/client/page\n */\n\nimport { useCallback, useEffect, useMemo, useState } from 'react'\nimport type { AnalyzeWire, EditableKey, EditableSettings, GitCredentialSpec, RepoSpec, RepoStatusWire, StateWire, TokenStatusWire } from '../settings/contract.ts'\nimport { clearToken, fetchState, messageOf, resetSettings, saveSettings, saveToken, syncRepos } from './api.ts'\n\n/** Sidebar label and page title. */\nexport const PANEL_TITLE = '观象'\n\nconst KB = 1024\nconst MB = 1024 * 1024\nconst MINUTE = 60 * 1000\n\ntype TabId = 'repos' | 'tokens' | 'download' | 'analyze' | 'advanced'\n\nconst TABS: readonly { id: TabId; label: string }[] = [\n { id: 'repos', label: '应用仓库' },\n { id: 'tokens', label: '访问令牌' },\n { id: 'download', label: '日志下载' },\n { id: 'analyze', label: '分析接口' },\n { id: 'advanced', label: '高级' },\n]\n\n/** Editable text form of the settings. */\ninterface Draft {\n reposDir: string\n repos: RepoSpec[]\n gitCredentials: GitCredentialSpec[]\n fetchIntervalMin: string\n maxAppsPerRequest: string\n dispatchTimeoutMin: string\n allowedHosts: string[]\n maxMb: string\n timeoutSec: string\n skillUpdatesEnabled: boolean\n skillMaxFiles: string\n skillMaxKb: string\n analyzeEnabled: boolean\n}\n\nfunction trimNumber(value: number): string {\n return String(Math.round(value * 100) / 100)\n}\n\nfunction toDraft(settings: EditableSettings): Draft {\n return {\n reposDir: settings.reposDir,\n repos: settings.repos.map(repo => ({ ...repo })),\n gitCredentials: settings.gitCredentials.map(credential => ({ ...credential })),\n fetchIntervalMin: trimNumber(settings.fetchIntervalMs / MINUTE),\n maxAppsPerRequest: String(settings.maxAppsPerRequest),\n dispatchTimeoutMin: trimNumber(settings.dispatchTimeoutMs / MINUTE),\n allowedHosts: [...settings.download.allowedHosts],\n maxMb: trimNumber(settings.download.maxBytes / MB),\n timeoutSec: trimNumber(settings.download.timeoutMs / 1000),\n skillUpdatesEnabled: settings.skillUpdates.enabled,\n skillMaxFiles: String(settings.skillUpdates.maxFiles),\n skillMaxKb: trimNumber(settings.skillUpdates.maxFileBytes / KB),\n analyzeEnabled: settings.analyze.enabled,\n }\n}\n\nfunction positive(text: string, label: string, allowZero = false): number {\n const value = Number(text.trim())\n if (text.trim() === '' || !Number.isFinite(value) || value < 0 || (!allowZero && value === 0)) throw new Error(`${label}必须是${allowZero ? '非负' : '正'}数`)\n return value\n}\n\nfunction fromDraft(draft: Draft): EditableSettings {\n const maxApps = positive(draft.maxAppsPerRequest, '单次应用数上限')\n if (!Number.isInteger(maxApps)) throw new Error('单次应用数上限必须是整数')\n const maxFiles = positive(draft.skillMaxFiles, '提议文件数上限')\n if (!Number.isInteger(maxFiles)) throw new Error('提议文件数上限必须是整数')\n return {\n reposDir: draft.reposDir.trim(),\n repos: draft.repos.map(repo => repo.branch === undefined || repo.branch.trim() === '' ? { url: repo.url.trim() } : { url: repo.url.trim(), branch: repo.branch.trim() }),\n gitCredentials: draft.gitCredentials.map(credential => ({\n url: credential.url.trim(),\n ...credential.alias === undefined || credential.alias.trim() === '' ? {} : { alias: credential.alias.trim() },\n username: credential.username.trim(),\n tokenEnv: credential.tokenEnv.trim(),\n })),\n fetchIntervalMs: Math.round(positive(draft.fetchIntervalMin, '更新间隔', true) * MINUTE),\n maxAppsPerRequest: maxApps,\n dispatchTimeoutMs: Math.round(positive(draft.dispatchTimeoutMin, '派发超时') * MINUTE),\n download: {\n allowedHosts: draft.allowedHosts.map(host => host.trim()).filter(host => host !== ''),\n maxBytes: Math.round(positive(draft.maxMb, '单文件大小上限') * MB),\n timeoutMs: Math.round(positive(draft.timeoutSec, '下载超时') * 1000),\n },\n skillUpdates: {\n enabled: draft.skillUpdatesEnabled,\n maxFiles,\n maxFileBytes: Math.round(positive(draft.skillMaxKb, '提议单文件大小上限') * KB),\n },\n analyze: { enabled: draft.analyzeEnabled },\n }\n}\n\nfunction sameSettings(draft: Draft, settings: EditableSettings): boolean {\n try {\n return JSON.stringify(fromDraft(draft)) === JSON.stringify(settings)\n } catch {\n // An unparsable draft differs from any saved settings.\n return false\n }\n}\n\nfunction formatTime(iso: string | number | undefined): string {\n if (iso === undefined) return ''\n const date = new Date(iso)\n return Number.isNaN(date.getTime()) ? '' : date.toLocaleString()\n}\n\nfunction phasePill(repo: RepoStatusWire | undefined): JSX.Element {\n if (repo === undefined) return <span className=\"gx__pill\"><span className=\"gx__dot\" />保存后拉取</span>\n if (repo.phase === 'syncing') return <span className=\"gx__pill gx__pill--warn\"><span className=\"gx__dot\" />拉取中</span>\n if (repo.available) return <span className=\"gx__pill gx__pill--ok\"><span className=\"gx__dot\" />就绪</span>\n if (repo.phase === 'ready' || repo.phase === 'failed') return <span className=\"gx__pill gx__pill--bad\"><span className=\"gx__dot\" />不可用</span>\n return <span className=\"gx__pill\"><span className=\"gx__dot\" />待拉取</span>\n}\n\nfunction Overridden({ keys, name }: { keys: readonly EditableKey[]; name: EditableKey }): JSX.Element | null {\n return keys.includes(name) ? <span className=\"gx__tag gx__tag--accent\">面板设置</span> : null\n}\n\n/**\n * Main-column page for the `main` slot.\n * @returns the page.\n */\nexport function GuanxiangPage(): JSX.Element {\n return (\n <section className=\"gx-page\" aria-label={PANEL_TITLE}>\n <div className=\"gx-page__content\">\n <GuanxiangPanel />\n </div>\n </section>\n )\n}\n\ntype Notice = { kind: 'ok' | 'error'; text: string } | undefined\n\n/**\n * Panel body: loads state, edits a draft, saves.\n * @returns the panel.\n */\nexport function GuanxiangPanel(): JSX.Element {\n const [state, setState] = useState<StateWire | undefined>()\n const [loadError, setLoadError] = useState<string | undefined>()\n const [draft, setDraft] = useState<Draft | undefined>()\n const [tab, setTab] = useState<TabId>('repos')\n const [busy, setBusy] = useState(false)\n const [notice, setNotice] = useState<Notice>()\n\n const adopt = useCallback((next: StateWire, resetDraft: boolean) => {\n setState(next)\n if (resetDraft) setDraft(toDraft(next.settings))\n }, [])\n\n const reload = useCallback(async (resetDraft: boolean) => {\n try {\n adopt(await fetchState(), resetDraft)\n setLoadError(undefined)\n } catch (error) {\n setLoadError(messageOf(error))\n }\n }, [adopt])\n\n useEffect(() => { void reload(true) }, [reload])\n\n const syncing = state?.repos.some(repo => repo.phase === 'syncing') === true\n useEffect(() => {\n if (!syncing) return\n const timer = setInterval(() => { void reload(false) }, 2000)\n return () => { clearInterval(timer) }\n }, [syncing, reload])\n\n const dirty = state !== undefined && draft !== undefined && !sameSettings(draft, state.settings)\n\n const run = async (action: () => Promise<StateWire>, success: string, resetDraft: boolean): Promise<StateWire | undefined> => {\n setBusy(true)\n setNotice(undefined)\n try {\n const next = await action()\n adopt(next, resetDraft)\n setNotice({ kind: 'ok', text: success })\n return next\n } catch (error) {\n setNotice({ kind: 'error', text: messageOf(error) })\n return undefined\n } finally {\n setBusy(false)\n }\n }\n\n const save = (): void => {\n if (draft === undefined) return\n let settings: EditableSettings\n try {\n settings = fromDraft(draft)\n } catch (error) {\n setNotice({ kind: 'error', text: messageOf(error) })\n return\n }\n void run(() => saveSettings(settings), '已保存,新的仓库会在后台拉取', true)\n }\n\n if (state === undefined || draft === undefined) {\n return (\n <div className=\"gx\">\n {loadError === undefined\n ? <div className=\"gx__loading\">加载中…</div>\n : <div className=\"gx__notice gx__notice--error\">{loadError} <button type=\"button\" className=\"gx__btn gx__btn--ghost\" onClick={() => { void reload(true) }}>重试</button></div>}\n </div>\n )\n }\n\n const available = state.repos.filter(repo => repo.available).length\n return (\n <div className=\"gx\">\n <header className=\"gx__head\">\n <div className=\"gx__headRow\">\n <h1 className=\"gx__title\">{PANEL_TITLE}</h1>\n <span className={`gx__pill ${available > 0 ? 'gx__pill--ok' : 'gx__pill--warn'}`}><span className=\"gx__dot\" />{available} 个应用可用</span>\n {syncing ? <span className=\"gx__pill gx__pill--warn\"><span className=\"gx__dot\" />拉取中</span> : null}\n </div>\n <div className=\"gx__meta\">观其象,知其因。在对话中输入 /guanxiang 描述问题并附上日志,观象会按应用派发分析。</div>\n <div className=\"gx__tabs\" role=\"tablist\">\n {TABS.map(item => (\n <button key={item.id} type=\"button\" role=\"tab\" className=\"gx__tab\" aria-selected={tab === item.id} onClick={() => { setTab(item.id) }}>{item.label}</button>\n ))}\n </div>\n </header>\n {state.overlayError === undefined ? null : <div className=\"gx__notice gx__notice--error\">面板设置文件未生效:{state.overlayError}。保存一次会用当前内容覆盖它。</div>}\n <div className=\"gx__body\" role=\"tabpanel\">\n {tab === 'repos' ? <ReposTab draft={draft} setDraft={setDraft} state={state} busy={busy || dirty} onSync={(url) => { void run(() => syncRepos(url), url === undefined ? '已开始重新拉取全部仓库' : '已开始重新拉取', false) }} /> : null}\n {tab === 'tokens'\n ? <TokensTab\n draft={draft}\n setDraft={setDraft}\n state={state}\n busy={busy}\n onAdd={async (credential, token) => {\n const saved = await run(() => saveSettings({ ...state.settings, gitCredentials: [...state.settings.gitCredentials, credential] }), token === '' ? `已添加 ${credential.url},请填入令牌` : `已添加 ${credential.url}`, false)\n const added = saved?.settings.gitCredentials[state.settings.gitCredentials.length]\n if (added === undefined) return false\n setDraft(current => current === undefined || current.gitCredentials.some(item => item.url === added.url) ? current : { ...current, gitCredentials: [...current.gitCredentials, added] })\n return token === '' || await run(() => saveToken(added.tokenEnv, token), `已添加 ${added.url} 并保存令牌,使用它的仓库会重新拉取`, false) !== undefined\n }}\n onSave={async (tokenEnv, value) => await run(() => saveToken(tokenEnv, value), `已保存 ${tokenEnv},使用它的仓库会重新拉取`, false) !== undefined}\n onClear={(tokenEnv) => { void run(() => clearToken(tokenEnv), `已清除面板保存的 ${tokenEnv}`, false) }}\n />\n : null}\n {tab === 'download' ? <DownloadTab draft={draft} setDraft={setDraft} overridden={state.overridden} /> : null}\n {tab === 'analyze'\n ? <AnalyzeTab\n draft={draft}\n setDraft={setDraft}\n analyze={state.analyze}\n credentialsAvailable={state.credentials.available}\n overridden={state.overridden}\n busy={busy}\n onSave={async value => await run(() => saveToken(state.analyze.tokenEnv, value), '已保存分析接口令牌,下一个请求起生效', false) !== undefined}\n onClear={() => { void run(() => clearToken(state.analyze.tokenEnv), '已清除面板保存的分析接口令牌', false) }}\n />\n : null}\n {tab === 'advanced' ? <AdvancedTab draft={draft} setDraft={setDraft} overridden={state.overridden} busy={busy} onReset={() => { void run(resetSettings, '已恢复为 cordis.yml 中的配置', true) }} /> : null}\n </div>\n {notice === undefined ? null : <div className={`gx__notice gx__notice--${notice.kind}`}>{notice.text}</div>}\n <div className=\"gx__saveBar\">\n <span className=\"gx__saveMsg\">{dirty ? '有未保存的修改' : '设置已保存'}</span>\n <button type=\"button\" className=\"gx__btn gx__btn--ghost\" disabled={!dirty || busy} onClick={() => { setDraft(toDraft(state.settings)); setNotice(undefined) }}>放弃修改</button>\n <button type=\"button\" className=\"gx__btn gx__btn--primary\" disabled={!dirty || busy} onClick={save}>保存</button>\n </div>\n </div>\n )\n}\n\ninterface TabProps {\n draft: Draft\n setDraft: (next: Draft) => void\n}\n\nfunction ReposTab({ draft, setDraft, state, busy, onSync }: TabProps & { state: StateWire; busy: boolean; onSync: (url?: string) => void }): JSX.Element {\n const [url, setUrl] = useState('')\n const [branch, setBranch] = useState('')\n const status = useMemo(() => new Map(state.repos.map(repo => [repo.url, repo])), [state.repos])\n const add = (): void => {\n const trimmed = url.trim()\n if (trimmed === '' || draft.repos.some(repo => repo.url === trimmed)) return\n setDraft({ ...draft, repos: [...draft.repos, branch.trim() === '' ? { url: trimmed } : { url: trimmed, branch: branch.trim() }] })\n setUrl('')\n setBranch('')\n }\n return (\n <section className=\"gx__sec\">\n <h2 className=\"gx__secTitle\">应用仓库 <Overridden keys={state.overridden} name=\"repos\" /></h2>\n <div className=\"gx__list\">\n {draft.repos.length === 0 ? <div className=\"gx__emptyRow\">还没有应用仓库。添加 git 地址后保存,观象会把仓库拉取到本机。</div> : null}\n {draft.repos.map((repo, index) => {\n const current = status.get(repo.url)\n const saved = current !== undefined && current.branch === repo.branch\n return (\n <div key={repo.url} className=\"gx__row gx__row--top\">\n <div className=\"gx__rowText\">\n <div className=\"gx__rowLabel\">\n <span className=\"gx__mono\">{repo.url}</span>\n {repo.branch === undefined ? null : <span className=\"gx__tag\">{repo.branch}</span>}\n {phasePill(saved ? current : undefined)}\n </div>\n {saved && current.app !== undefined\n ? <div className=\"gx__rowSummary\">{current.app.name}(<span className=\"gx__mono\">{current.app.id}</span>)· SKILL <span className=\"gx__mono\">/{current.app.skill}</span>{current.activeRuns > 0 ? ` · ${current.activeRuns} 个分析进行中` : ''}</div>\n : null}\n {saved && current.app !== undefined ? <div className=\"gx__rowSummary\">{current.app.description}</div> : null}\n {saved && current.commit !== undefined\n ? <div className=\"gx__rowSummary\">提交 <span className=\"gx__mono\">{current.commit.slice(0, 8)}</span>({formatTime(current.commitTime)})· 拉取于 {formatTime(current.syncedAt)} · <span className=\"gx__mono\">{current.dir}</span></div>\n : null}\n {saved && current.error !== undefined ? <div className=\"gx__rowError\">{current.error}</div> : null}\n </div>\n <div className=\"gx__rowCtl\">\n {saved ? <button type=\"button\" className=\"gx__btn\" disabled={busy || current.phase === 'syncing'} onClick={() => { onSync(repo.url) }}>重新拉取</button> : null}\n <button type=\"button\" className=\"gx__btn gx__btn--danger\" onClick={() => { setDraft({ ...draft, repos: draft.repos.filter((_, position) => position !== index) }) }}>删除</button>\n </div>\n </div>\n )\n })}\n <div className=\"gx__addRow\">\n <input className=\"gx__input\" placeholder=\"git 地址,例如 git@github.com:example/order-service.git\" value={url} onChange={(event) => { setUrl(event.target.value) }} onKeyDown={(event) => { if (event.key === 'Enter') add() }} />\n <input className=\"gx__input gx__input--branch\" placeholder=\"分支(可选)\" value={branch} onChange={(event) => { setBranch(event.target.value) }} onKeyDown={(event) => { if (event.key === 'Enter') add() }} />\n <button type=\"button\" className=\"gx__btn\" disabled={url.trim() === ''} onClick={add}>添加</button>\n </div>\n </div>\n <p className=\"gx__secFoot\">使用本机已有的 git 凭据(SSH key 或 credential helper)拉取;https 地址可在「访问令牌」中配置个人访问令牌。不留分支时跟随远端默认分支。每个仓库需包含 <span className=\"gx__mono\">.dsh/guanxiang.yaml</span> 与其中声明的日志分析 SKILL。删除地址不会删除本地目录。</p>\n {state.repos.length > 0 ? <div><button type=\"button\" className=\"gx__btn\" disabled={busy} onClick={() => { onSync() }}>重新拉取全部</button></div> : null}\n </section>\n )\n}\n\nconst DEFAULT_USERNAME = 'oauth2'\n/** Prefix of the credential keys the panel allocates; namespaced so an unrelated `GITLAB_TOKEN` in the environment is not picked up. */\nconst DEFAULT_TOKEN_ENV = 'GUANXIANG_GITLAB_TOKEN'\n\n/** Credential store layers of `@deepseek-ai/dsh-credentials-local` other than its own file. */\nconst TOKEN_SOURCES: Readonly<Record<string, string>> = { 'env': '启动环境变量', 'project-env': '项目 .env', 'user-env': '$DSH_HOME/.env' }\n\nfunction tokenPill(token: TokenStatusWire | undefined): JSX.Element {\n if (token === undefined) return <span className=\"gx__pill\"><span className=\"gx__dot\" />保存后设置令牌</span>\n if (token.error !== undefined) return <span className=\"gx__pill gx__pill--bad\"><span className=\"gx__dot\" />无法读取</span>\n if (!token.configured) return <span className=\"gx__pill gx__pill--warn\"><span className=\"gx__dot\" />未设置令牌</span>\n const source = token.source === undefined || token.source === 'file' ? undefined : TOKEN_SOURCES[token.source] ?? token.source\n return <span className=\"gx__pill gx__pill--ok\"><span className=\"gx__dot\" />已设置{source === undefined ? '' : `(来自${source})`}</span>\n}\n\n/**\n * First of `GUANXIANG_GITLAB_TOKEN`, `GUANXIANG_GITLAB_TOKEN_2`, … that no\n * saved or drafted entry uses.\n * @param used - keys already in use.\n * @returns a free key.\n */\nfunction freeTokenEnv(used: ReadonlySet<string>): string {\n if (!used.has(DEFAULT_TOKEN_ENV)) return DEFAULT_TOKEN_ENV\n let index = 2\n while (used.has(`${DEFAULT_TOKEN_ENV}_${index}`)) index += 1\n return `${DEFAULT_TOKEN_ENV}_${index}`\n}\n\nfunction TokensTab({ draft, setDraft, state, busy, onAdd, onSave, onClear }: TabProps & {\n state: StateWire\n busy: boolean\n /** Saves the entry, then its token; resolves whether both succeeded. */\n onAdd: (credential: GitCredentialSpec, token: string) => Promise<boolean>\n onSave: (tokenEnv: string, value: string) => Promise<boolean>\n onClear: (tokenEnv: string) => void\n}): JSX.Element {\n const [url, setUrl] = useState('')\n const [alias, setAlias] = useState('')\n const [token, setToken] = useState('')\n const [addError, setAddError] = useState<string | undefined>()\n // Spans both requests of one addition; `busy` drops between them.\n const [adding, setAdding] = useState(false)\n const [values, setValues] = useState<Record<string, string>>({})\n const tokens = useMemo(() => new Map(state.credentials.tokens.map(item => [item.tokenEnv, item])), [state.credentials.tokens])\n const saved = useMemo(() => new Set(state.settings.gitCredentials.map(credential => credential.tokenEnv)), [state.settings.gitCredentials])\n const complete = url.trim() !== '' && alias.trim() !== '' && token.trim() !== ''\n const add = (): void => {\n if (!complete || busy || adding) return\n const address = url.trim()\n if (state.settings.gitCredentials.some(credential => credential.url === address)) {\n setAddError('这个地址已经添加过了,请在上面的列表里更新它的令牌。')\n return\n }\n setAddError(undefined)\n setAdding(true)\n const tokenEnv = freeTokenEnv(new Set([...saved, ...draft.gitCredentials.map(credential => credential.tokenEnv)]))\n void onAdd({ url: address, alias: alias.trim(), username: DEFAULT_USERNAME, tokenEnv }, token.trim()).then((ok) => {\n if (!ok) return\n setUrl('')\n setAlias('')\n setToken('')\n }).finally(() => { setAdding(false) })\n }\n const save = (name: string): void => {\n const value = values[name]?.trim() ?? ''\n if (value === '' || busy || adding) return\n void onSave(name, value).then((ok) => { if (ok) setValues(current => ({ ...current, [name]: '' })) })\n }\n const submitOnEnter = (event: { key: string }): void => { if (event.key === 'Enter') add() }\n return (\n <section className=\"gx__sec\">\n <h2 className=\"gx__secTitle\">GitLab 访问令牌 <Overridden keys={state.overridden} name=\"gitCredentials\" /></h2>\n {state.credentials.available ? null : <div className=\"gx__notice gx__notice--error\">当前 DSH 组合没有加载凭据服务(@deepseek-ai/dsh-credentials-local),无法保存或读取令牌。</div>}\n <div className=\"gx__list\">\n {draft.gitCredentials.length === 0 ? <div className=\"gx__emptyRow\">还没有访问令牌。用 https 地址拉取 GitLab 私有仓库时,在下面填入 GitLab 地址、令牌别名和令牌。</div> : null}\n {draft.gitCredentials.map((credential, index) => {\n const status = saved.has(credential.tokenEnv) ? tokens.get(credential.tokenEnv) : undefined\n const value = values[credential.tokenEnv] ?? ''\n return (\n <div key={credential.url} className=\"gx__row gx__row--top\">\n <div className=\"gx__rowText\">\n <div className=\"gx__rowLabel\">\n <span>{credential.alias ?? credential.url}</span>\n {tokenPill(status)}\n </div>\n {credential.alias === undefined ? null : <div className=\"gx__rowSummary gx__mono\">{credential.url}</div>}\n {status?.error === undefined ? null : <div className=\"gx__rowError\">{status.error}</div>}\n {status !== undefined && status.writable\n ? (\n <div className=\"gx__addRow gx__addRow--flush\">\n <input className=\"gx__input gx__mono\" type=\"password\" autoComplete=\"new-password\" spellCheck={false} placeholder={status.configured ? '输入新令牌以替换' : '粘贴令牌'} value={value} onChange={(event) => { setValues({ ...values, [credential.tokenEnv]: event.target.value }) }} onKeyDown={(event) => { if (event.key === 'Enter') save(credential.tokenEnv) }} />\n <button type=\"button\" className=\"gx__btn\" disabled={busy || adding || value.trim() === ''} onClick={() => { save(credential.tokenEnv) }}>保存令牌</button>\n {status.configured && status.source === 'file' ? <button type=\"button\" className=\"gx__btn gx__btn--ghost\" disabled={busy} onClick={() => { onClear(credential.tokenEnv) }}>清除</button> : null}\n </div>\n )\n : null}\n </div>\n <div className=\"gx__rowCtl\">\n <button type=\"button\" className=\"gx__btn gx__btn--danger\" onClick={() => { setDraft({ ...draft, gitCredentials: draft.gitCredentials.filter((_, position) => position !== index) }) }}>删除</button>\n </div>\n </div>\n )\n })}\n <div className=\"gx__addForm\">\n <div className=\"gx__addRow gx__addRow--flush\">\n <label className=\"gx__field\">GitLab 地址<input className=\"gx__input\" placeholder=\"https://gitlab.example.com\" value={url} onChange={(event) => { setUrl(event.target.value) }} onKeyDown={submitOnEnter} /></label>\n <label className=\"gx__field\">令牌别名<input className=\"gx__input\" placeholder=\"例如 guanxiang\" value={alias} onChange={(event) => { setAlias(event.target.value) }} onKeyDown={submitOnEnter} /></label>\n <label className=\"gx__field\">令牌<input className=\"gx__input gx__mono\" type=\"password\" autoComplete=\"new-password\" spellCheck={false} placeholder=\"粘贴个人访问令牌\" value={token} onChange={(event) => { setToken(event.target.value) }} onKeyDown={submitOnEnter} /></label>\n <button type=\"button\" className=\"gx__btn gx__btn--end\" disabled={busy || adding || !complete} onClick={add}>添加</button>\n </div>\n {addError === undefined ? null : <div className=\"gx__rowError\">{addError}</div>}\n </div>\n </div>\n <p className=\"gx__secFoot\">地址在这个前缀下的 https 仓库使用对应令牌(多个匹配时取路径最长的),ssh 地址不受影响。拉取需要 read_repository 权限,开启 SKILL 改进时还需要 write_repository。令牌保存在 DSH 凭据库(默认 $DSH_HOME/.credentials.yaml,仅本机用户可读),面板只显示是否已设置;令牌只经环境变量交给 git,不写入设置文件、仓库配置、日志或模型上下文。</p>\n </section>\n )\n}\n\nfunction DownloadTab({ draft, setDraft, overridden }: TabProps & { overridden: readonly EditableKey[] }): JSX.Element {\n const [host, setHost] = useState('')\n const add = (): void => {\n const trimmed = host.trim().toLowerCase()\n if (trimmed === '' || draft.allowedHosts.includes(trimmed)) return\n setDraft({ ...draft, allowedHosts: [...draft.allowedHosts, trimmed] })\n setHost('')\n }\n return (\n <>\n <section className=\"gx__sec\">\n <h2 className=\"gx__secTitle\">允许下载的域名 <Overridden keys={overridden} name=\"download\" /></h2>\n <div className=\"gx__list\">\n {draft.allowedHosts.length === 0 ? <div className=\"gx__emptyRow\">未配置域名,消息中的日志下载链接不会被下载。</div> : null}\n {draft.allowedHosts.map(item => (\n <div key={item} className=\"gx__row\">\n <div className=\"gx__rowText\"><span className=\"gx__mono\">{item}</span></div>\n <div className=\"gx__rowCtl\"><button type=\"button\" className=\"gx__btn gx__btn--danger\" onClick={() => { setDraft({ ...draft, allowedHosts: draft.allowedHosts.filter(entry => entry !== item) }) }}>删除</button></div>\n </div>\n ))}\n <div className=\"gx__addRow\">\n <input className=\"gx__input\" placeholder=\"主机名,例如 oss.example.com\" value={host} onChange={(event) => { setHost(event.target.value) }} onKeyDown={(event) => { if (event.key === 'Enter') add() }} />\n <button type=\"button\" className=\"gx__btn\" disabled={host.trim() === ''} onClick={add}>添加</button>\n </div>\n </div>\n <p className=\"gx__secFoot\">只填主机名,同时允许它的子域名。下载不携带任何鉴权信息,每次重定向都会重新校验域名。</p>\n </section>\n <section className=\"gx__sec\">\n <h2 className=\"gx__secTitle\">限制</h2>\n <div className=\"gx__list\">\n <NumberRow label=\"单文件大小上限\" unit=\"MB\" value={draft.maxMb} onChange={(value) => { setDraft({ ...draft, maxMb: value }) }} />\n <NumberRow label=\"单文件下载超时\" unit=\"秒\" value={draft.timeoutSec} onChange={(value) => { setDraft({ ...draft, timeoutSec: value }) }} />\n </div>\n </section>\n </>\n )\n}\n\nconst TOPICS_STATUS: Readonly<Record<AnalyzeWire['topics'], { pill: string; text: string }>> = {\n ready: { pill: 'gx__pill--ok', text: '飞书渠道就绪' },\n missing: { pill: 'gx__pill--bad', text: '未找到飞书渠道' },\n incompatible: { pill: 'gx__pill--bad', text: '飞书渠道版本不兼容' },\n}\n\nfunction AnalyzeTab({ draft, setDraft, analyze, credentialsAvailable, overridden, busy, onSave, onClear }: TabProps & {\n analyze: AnalyzeWire\n credentialsAvailable: boolean\n overridden: readonly EditableKey[]\n busy: boolean\n onSave: (value: string) => Promise<boolean>\n onClear: () => void\n}): JSX.Element {\n const [value, setValue] = useState('')\n const token = analyze.token\n const save = (): void => {\n const trimmed = value.trim()\n if (trimmed === '' || busy) return\n void onSave(trimmed).then((ok) => { if (ok) setValue('') })\n }\n const topics = TOPICS_STATUS[analyze.topics]\n const endpoint = new URL(analyze.route.slice(1), document.baseURI).href\n return (\n <>\n <section className=\"gx__sec\">\n <h2 className=\"gx__secTitle\">日志平台分析接口</h2>\n <div className=\"gx__list\">\n <div className=\"gx__row\">\n <div className=\"gx__rowText\">\n <div className=\"gx__rowLabel\">开启接口 <Overridden keys={overridden} name=\"analyze\" /><span className={`gx__pill ${topics.pill}`}><span className=\"gx__dot\" />{topics.text}</span></div>\n <div className=\"gx__rowSummary\">日志平台调用接口后,观象经飞书渠道(dsh-channels 0.8 及以上)在目标群发出分析卡片,并在卡片下的话题里开始分析;群内成员都可以在话题里继续追问。关闭时接口回复 404。</div>\n {analyze.topics === 'ready' ? null : <div className=\"gx__rowError\">{analyze.topics === 'missing' ? '接口需要 dsh-channels 0.8 及以上版本并已加载;dsh-channels 0.7 自带同名接口,升级前由它提供。' : '请把观象与 dsh-channels 升级到相互兼容的版本。'}</div>}\n </div>\n <div className=\"gx__rowCtl\"><input type=\"checkbox\" className=\"gx__check\" aria-label=\"开启分析接口\" checked={draft.analyzeEnabled} onChange={(event) => { setDraft({ ...draft, analyzeEnabled: event.target.checked }) }} /></div>\n </div>\n <div className=\"gx__row gx__row--top\">\n <div className=\"gx__rowText\">\n <div className=\"gx__rowLabel\">访问令牌 <span className=\"gx__tag gx__mono\">{analyze.tokenEnv}</span>{credentialsAvailable ? tokenPill(token) : null}</div>\n <div className=\"gx__rowSummary\">日志平台以 <span className=\"gx__mono\">Authorization: Bearer <令牌></span> 调用接口。令牌未设置时接口回复 503。</div>\n {credentialsAvailable ? null : <div className=\"gx__rowError\">当前 DSH 组合没有加载凭据服务(@deepseek-ai/dsh-credentials-local),无法保存或读取令牌。</div>}\n {token?.error === undefined ? null : <div className=\"gx__rowError\">{token.error}</div>}\n {token !== undefined && token.writable\n ? (\n <div className=\"gx__addRow gx__addRow--flush\">\n <input className=\"gx__input gx__mono\" type=\"password\" autoComplete=\"new-password\" spellCheck={false} placeholder={token.configured ? '输入新令牌以替换' : '粘贴令牌'} value={value} onChange={(event) => { setValue(event.target.value) }} onKeyDown={(event) => { if (event.key === 'Enter') save() }} />\n <button type=\"button\" className=\"gx__btn\" disabled={busy || value.trim() === ''} onClick={save}>保存令牌</button>\n {token.configured && token.source === 'file' ? <button type=\"button\" className=\"gx__btn gx__btn--ghost\" disabled={busy} onClick={onClear}>清除</button> : null}\n </div>\n )\n : null}\n </div>\n </div>\n </div>\n </section>\n <section className=\"gx__sec\">\n <h2 className=\"gx__secTitle\">调用方式</h2>\n <div className=\"gx__list\">\n <div className=\"gx__row\"><div className=\"gx__rowText\"><div className=\"gx__rowLabel\">地址</div><div className=\"gx__rowSummary gx__mono\">POST {endpoint}</div></div></div>\n <div className=\"gx__row\"><div className=\"gx__rowText\"><div className=\"gx__rowLabel\">请求头</div><div className=\"gx__rowSummary gx__mono\">Authorization: Bearer <令牌> · Idempotency-Key: <1-200 个可见 ASCII 字符> · Content-Type: application/json</div></div></div>\n <div className=\"gx__row\"><div className=\"gx__rowText\"><div className=\"gx__rowLabel\">请求体</div><div className=\"gx__rowSummary gx__mono\">requesterUserId, triggeredAt, app, errorCode, logDetails[{'{'}name, url{'}'}], chatId, prompt</div></div></div>\n <div className=\"gx__row\"><div className=\"gx__rowText\"><div className=\"gx__rowLabel\">响应</div><div className=\"gx__rowSummary\">202 已发出分析卡片(同一 Idempotency-Key 重试返回同一张卡片);400/401/404/405/409/413/415 请求问题;403 目标群未授权;502 卡片发送失败;503 飞书未连接或令牌未设置。字段说明见观象 README。</div></div></div>\n </div>\n </section>\n </>\n )\n}\n\nfunction AdvancedTab({ draft, setDraft, overridden, busy, onReset }: TabProps & { overridden: readonly EditableKey[]; busy: boolean; onReset: () => void }): JSX.Element {\n return (\n <>\n <section className=\"gx__sec\">\n <h2 className=\"gx__secTitle\">仓库</h2>\n <div className=\"gx__list\">\n <div className=\"gx__row\">\n <div className=\"gx__rowText\">\n <div className=\"gx__rowLabel\">拉取目录 <Overridden keys={overridden} name=\"reposDir\" /></div>\n <div className=\"gx__rowSummary\">每个仓库拉取到该目录下的同名子目录,观象只读使用。</div>\n </div>\n <div className=\"gx__rowCtl\"><input className=\"gx__input gx__input--wide gx__mono\" value={draft.reposDir} onChange={(event) => { setDraft({ ...draft, reposDir: event.target.value }) }} /></div>\n </div>\n <NumberRow label=\"更新间隔\" summary=\"输入 /guanxiang 时,距上次拉取超过该时间的仓库会先更新;0 表示每次都更新。\" unit=\"分钟\" value={draft.fetchIntervalMin} overridden={overridden.includes('fetchIntervalMs')} onChange={(value) => { setDraft({ ...draft, fetchIntervalMin: value }) }} />\n </div>\n </section>\n <section className=\"gx__sec\">\n <h2 className=\"gx__secTitle\">派发</h2>\n <div className=\"gx__list\">\n <NumberRow label=\"单次应用数上限\" summary=\"一次派发最多同时分析的应用数,不应超过 DSH 的活动子 Agent 上限(默认 8)。\" unit=\"个\" value={draft.maxAppsPerRequest} overridden={overridden.includes('maxAppsPerRequest')} onChange={(value) => { setDraft({ ...draft, maxAppsPerRequest: value }) }} />\n <NumberRow label=\"派发超时\" summary=\"等待全部子 Agent 的最长时间,超时后停止仍在运行的子 Agent。\" unit=\"分钟\" value={draft.dispatchTimeoutMin} overridden={overridden.includes('dispatchTimeoutMs')} onChange={(value) => { setDraft({ ...draft, dispatchTimeoutMin: value }) }} />\n </div>\n </section>\n <section className=\"gx__sec\">\n <h2 className=\"gx__secTitle\">SKILL 改进</h2>\n <div className=\"gx__list\">\n <div className=\"gx__row\">\n <div className=\"gx__rowText\">\n <div className=\"gx__rowLabel\">允许提出 SKILL 修改 <Overridden keys={overridden} name=\"skillUpdates\" /></div>\n <div className=\"gx__rowSummary\">子 Agent 发现应用的日志分析 SKILL 有欠缺时可以写出修改提议;经用户授权后,观象经 dsh-repo 把它提交到新分支并创建合并请求(GitLab 或 GitHub,需要安装 dsh-repo 并配置该仓库主机的令牌)。</div>\n </div>\n <div className=\"gx__rowCtl\"><input type=\"checkbox\" className=\"gx__check\" aria-label=\"允许提出 SKILL 修改\" checked={draft.skillUpdatesEnabled} onChange={(event) => { setDraft({ ...draft, skillUpdatesEnabled: event.target.checked }) }} /></div>\n </div>\n <NumberRow label=\"提议文件数上限\" unit=\"个\" value={draft.skillMaxFiles} onChange={(value) => { setDraft({ ...draft, skillMaxFiles: value }) }} />\n <NumberRow label=\"提议单文件大小上限\" unit=\"KB\" value={draft.skillMaxKb} onChange={(value) => { setDraft({ ...draft, skillMaxKb: value }) }} />\n </div>\n </section>\n <section className=\"gx__sec\">\n <h2 className=\"gx__secTitle\">面板设置</h2>\n <div className=\"gx__list\">\n <div className=\"gx__row\">\n <div className=\"gx__rowText\">\n <div className=\"gx__rowLabel\">恢复 cordis.yml 配置</div>\n <div className=\"gx__rowSummary\">删除面板保存的全部设置($DSH_HOME/guanxiang/settings.json 中的覆盖值)。</div>\n </div>\n <div className=\"gx__rowCtl\"><button type=\"button\" className=\"gx__btn gx__btn--danger\" disabled={busy || overridden.length === 0} onClick={onReset}>恢复</button></div>\n </div>\n </div>\n </section>\n </>\n )\n}\n\nfunction NumberRow({ label, summary, unit, value, overridden = false, onChange }: { label: string; summary?: string; unit: string; value: string; overridden?: boolean; onChange: (value: string) => void }): JSX.Element {\n return (\n <div className=\"gx__row\">\n <div className=\"gx__rowText\">\n <div className=\"gx__rowLabel\">{label}{overridden ? <span className=\"gx__tag gx__tag--accent\">面板设置</span> : null}</div>\n {summary === undefined ? null : <div className=\"gx__rowSummary\">{summary}</div>}\n </div>\n <div className=\"gx__rowCtl\">\n <input className=\"gx__input gx__input--num\" inputMode=\"decimal\" value={value} onChange={(event) => { onChange(event.target.value) }} />\n <span className=\"gx__unit\">{unit}</span>\n </div>\n </div>\n )\n}\n","/**\n * 「观象」页面样式。使用 DSH 语义 token(`--dsw-alias-*`)并带中性回退,\n * 页面随当前主题变化。\n *\n * @module dsh-guanxiang/client/styles\n */\n\nconst STYLE_ATTRIBUTE = 'data-dsh-guanxiang-css'\n\nconst CSS = `\n.gx-page{width:100%;height:100%;min-width:0;min-height:0;overflow:auto;scrollbar-gutter:stable;background:var(--dsw-alias-bg-base,#fff)}\n.gx-page__content{box-sizing:border-box;max-width:816px;margin:0 auto;padding:18px clamp(24px,4vw,48px) 48px}\n[data-platform='darwin'] .gx-page__content{padding-top:calc(18px + var(--dsh-frame-top-clearance,0px))}\n.gx{--gx-fg:var(--dsw-alias-label-primary,#1f2328);--gx-fg2:var(--dsw-alias-label-secondary,#5c6169);--gx-fg3:var(--dsw-alias-label-tertiary,#8a8f98);--gx-dim:var(--dsw-alias-label-dimmed,#b0b4ba);--gx-bg:var(--dsw-alias-bg-base,#fff);--gx-line:var(--dsw-alias-border-l2,rgba(0,0,0,.12));--gx-hover:var(--dsw-alias-interactive-bg-hover,rgba(0,0,0,.05));--gx-accent:var(--dsw-alias-state-business-primary,#0a67d3);--gx-ok:var(--dsw-alias-state-success-primary,#0a7d33);--gx-warn:var(--dsw-alias-state-warn-primary,#a15c00);--gx-bad:var(--dsw-alias-state-error-primary,#c62828);--gx-mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;display:flex;flex-direction:column;gap:14px;width:100%;max-width:720px;color:var(--gx-fg);font-size:13px;line-height:20px}\n.gx__head{position:sticky;top:0;z-index:2;display:flex;flex-direction:column;gap:4px;padding:10px 0 6px;background:var(--gx-bg)}\n.gx__headRow{display:flex;align-items:center;gap:8px;flex-wrap:wrap}\n.gx__title{margin:0 2px 0 0;font-size:20px;font-weight:500;line-height:28px}\n.gx__meta{color:var(--gx-fg3);font-size:12px}\n.gx__mono{font-family:var(--gx-mono);font-size:12px}\n.gx__pill{display:inline-flex;align-items:center;gap:5px;padding:0 8px;border-radius:999px;font-size:12px;line-height:20px;white-space:nowrap;color:var(--gx-fg3);background:color-mix(in srgb,currentColor 10%,transparent)}\n.gx__pill--ok{color:var(--gx-ok)}\n.gx__pill--warn{color:var(--gx-warn)}\n.gx__pill--bad{color:var(--gx-bad)}\n.gx__dot{width:6px;height:6px;border-radius:50%;background:currentColor;flex:none}\n.gx__tabs{display:flex;align-items:center;gap:18px;border-bottom:1px solid var(--gx-line);overflow-x:auto;scrollbar-width:none}\n.gx__tab{display:inline-flex;align-items:center;min-height:34px;padding:0;border:0;border-bottom:2px solid transparent;background:transparent;color:var(--gx-fg2);font:inherit;font-size:13px;cursor:pointer;white-space:nowrap}\n.gx__tab:hover{color:var(--gx-fg)}\n.gx__tab[aria-selected=\"true\"]{color:var(--gx-fg);border-bottom-color:currentColor;font-weight:600}\n.gx__body{display:flex;flex-direction:column;gap:22px;padding:4px 0 8px}\n.gx__sec{display:flex;flex-direction:column;gap:6px;margin:0}\n.gx__secTitle{margin:0;font-size:12px;font-weight:600;line-height:18px;color:var(--gx-fg3);letter-spacing:.02em}\n.gx__secFoot{margin:0;color:var(--gx-fg3);font-size:12px;line-height:18px}\n.gx__list{display:flex;flex-direction:column;border:1px solid var(--gx-line);border-radius:10px}\n.gx__list>*+*{border-top:1px solid var(--gx-line)}\n.gx__row{display:flex;align-items:center;gap:16px;padding:11px 14px;min-height:28px}\n.gx__row--top{align-items:flex-start}\n.gx__rowText{display:flex;flex-direction:column;gap:2px;flex:1 1 auto;min-width:0}\n.gx__rowLabel{display:flex;align-items:center;gap:6px;flex-wrap:wrap;overflow-wrap:anywhere}\n.gx__rowSummary{color:var(--gx-fg3);font-size:12px;line-height:18px;overflow-wrap:anywhere}\n.gx__rowError{color:var(--gx-bad);font-size:12px;line-height:18px;overflow-wrap:anywhere;white-space:pre-wrap}\n.gx__rowCtl{flex:none;display:flex;align-items:center;gap:6px;justify-content:flex-end}\n.gx__tag{display:inline-flex;align-items:center;padding:0 5px;border-radius:4px;font-size:11px;line-height:16px;white-space:nowrap;color:var(--gx-fg2);background:var(--gx-hover)}\n.gx__tag--accent{color:var(--gx-accent);background:color-mix(in srgb,var(--gx-accent) 10%,transparent)}\n.gx__input{box-sizing:border-box;width:100%;min-width:0;height:30px;padding:0 10px;border:1px solid var(--gx-line);border-radius:7px;background:var(--dsw-alias-bg-layer-1,transparent);color:inherit;font:inherit;font-size:13px;outline:none}\n.gx__input:focus{border-color:var(--gx-accent)}\n.gx__input--num{width:120px;text-align:right;font-variant-numeric:tabular-nums}\n.gx__input--wide{width:320px}\n.gx__check{width:16px;height:16px;margin:0;accent-color:var(--gx-accent);cursor:pointer}\n.gx__unit{min-width:36px;color:var(--gx-fg3);font-size:12px}\n.gx__addRow{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:10px 14px}\n.gx__addRow .gx__input{flex:1 1 160px;width:auto}\n.gx__addRow .gx__input--branch{flex:0 1 140px}\n.gx__addRow--flush{padding:6px 0 0}\n.gx__addForm{display:flex;flex-direction:column;gap:6px;padding:10px 14px}\n.gx__field{display:flex;flex-direction:column;gap:2px;flex:1 1 160px;color:var(--gx-fg3);font-size:12px}\n.gx__field .gx__input{flex:none;width:100%}\n.gx__btn--end{align-self:flex-end;height:30px}\n.gx__emptyRow{padding:11px 14px;color:var(--gx-fg3);font-size:12px}\n.gx__btn{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;gap:4px;height:28px;padding:0 12px;border:1px solid var(--gx-line);border-radius:7px;background:transparent;color:inherit;font:inherit;font-size:13px;cursor:pointer;white-space:nowrap}\n.gx__btn:hover:not(:disabled){background:var(--gx-hover)}\n.gx__btn:disabled{color:var(--gx-dim);cursor:default}\n.gx__btn--primary{background:var(--dsw-alias-button-primary-fill,var(--gx-accent));border-color:transparent;color:var(--dsw-alias-label-primary-foreground,#fff)}\n.gx__btn--primary:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover,#0b5cba)}\n.gx__btn--primary:disabled{opacity:.45;color:var(--dsw-alias-label-primary-foreground,#fff)}\n.gx__btn--ghost{border-color:transparent;color:var(--gx-fg2)}\n.gx__btn--danger{color:var(--gx-bad)}\n.gx__btn:focus-visible,.gx__tab:focus-visible{outline:2px solid var(--gx-accent);outline-offset:2px}\n.gx__notice{padding:8px 12px;border-radius:8px;font-size:12px;line-height:18px;overflow-wrap:anywhere}\n.gx__notice--ok{color:var(--gx-ok);background:color-mix(in srgb,var(--gx-ok) 9%,transparent)}\n.gx__notice--error{color:var(--gx-bad);background:color-mix(in srgb,var(--gx-bad) 8%,transparent)}\n.gx__saveBar{position:sticky;bottom:0;z-index:2;display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:10px 0;border-top:1px solid var(--gx-line);background:var(--gx-bg)}\n.gx__saveMsg{flex:1;min-width:0;color:var(--gx-fg2);font-size:12px}\n.gx__loading{padding:16px 0;color:var(--gx-fg3);font-size:12px}\n`\n\n/**\n * Install the page stylesheet once.\n * @returns disposer removing it.\n */\nexport function installStyles(): () => void {\n const existing = document.querySelector(`style[${STYLE_ATTRIBUTE}]`)\n if (existing !== null) return () => {}\n const element = document.createElement('style')\n element.setAttribute(STYLE_ATTRIBUTE, '')\n element.textContent = CSS\n document.head.append(element)\n return () => { element.remove() }\n}\n","/**\n * 观象 client half:左侧栏全局入口「观象」+ 主区整页设置面板。\n *\n * 只依赖平台核心的 `slots` 服务与 react(bundle 里 react 走平台模块表,\n * 其余全部内联);页面数据来自 Host 半侧的 `/guanxiang/*` 路由。\n *\n * @module dsh-guanxiang/client\n */\n\nimport { GuanxiangIcon } from './icon.tsx'\nimport { GuanxiangPage, PANEL_TITLE } from './page.tsx'\nimport { installStyles } from './styles.ts'\n\n/** Slots runtime surface this bundle uses: list slots by `id`, keyed slots by `key`. */\nexport interface ClientSlots {\n inject(slot: string, contribution: () => unknown): void\n register(\n declaration:\n | { name: string; id: string; order?: number; label?: () => string }\n | { name: string; key: string },\n component: (props: never) => unknown,\n ): () => void\n}\n\n/** Client plugin context. */\nexport interface ClientContext {\n slots: ClientSlots\n effect?(callback: () => void | (() => void), label?: string): void\n}\n\n/** Cordis client plugin name. */\nexport const name = 'dsh-guanxiang'\n\n/** Required client services: the Slots registry is part of the web shell core. */\nexport const inject = ['slots']\n\n/**\n * Main panel id: the `sidebar.panellist` row id and the matching `main` slot\n * key. Must not change once released: DSH keys navigation state by it.\n */\nexport const PANEL_ID = 'guanxiang'\n/** Left-sidebar row order (dsh-channels uses 40). */\nexport const PANEL_ORDER = 45\n\n/**\n * Mount the left-sidebar entry, its main-column page, and the stylesheet.\n * @param ctx - client plugin context carrying the slots registry.\n */\nexport function apply(ctx: ClientContext): void {\n if (typeof ctx.effect === 'function') ctx.effect(() => installStyles(), 'dsh-guanxiang: panel styles')\n else installStyles()\n ctx.slots.inject('main', () => ctx.slots.register({ name: 'main', key: PANEL_ID }, GuanxiangPage))\n ctx.slots.inject('sidebar.panellist', () => ctx.slots.register({\n name: 'sidebar.panellist',\n id: PANEL_ID,\n order: PANEL_ORDER,\n label: () => PANEL_TITLE,\n }, GuanxiangIcon))\n}\n"],"mappings":"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"}
|